1221167Sgnn/*- 2221167Sgnn * Copyright(c) 2002-2011 Exar Corp. 3221167Sgnn * All rights reserved. 4221167Sgnn * 5221167Sgnn * Redistribution and use in source and binary forms, with or without 6221167Sgnn * modification are permitted provided the following conditions are met: 7221167Sgnn * 8221167Sgnn * 1. Redistributions of source code must retain the above copyright notice, 9221167Sgnn * this list of conditions and the following disclaimer. 10221167Sgnn * 11221167Sgnn * 2. Redistributions in binary form must reproduce the above copyright 12221167Sgnn * notice, this list of conditions and the following disclaimer in the 13221167Sgnn * documentation and/or other materials provided with the distribution. 14221167Sgnn * 15221167Sgnn * 3. Neither the name of the Exar Corporation nor the names of its 16221167Sgnn * contributors may be used to endorse or promote products derived from 17221167Sgnn * this software without specific prior written permission. 18221167Sgnn * 19221167Sgnn * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20221167Sgnn * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21221167Sgnn * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22221167Sgnn * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 23221167Sgnn * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24221167Sgnn * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25221167Sgnn * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26221167Sgnn * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27221167Sgnn * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28221167Sgnn * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29221167Sgnn * POSSIBILITY OF SUCH DAMAGE. 30221167Sgnn */ 31221167Sgnn/*$FreeBSD: releng/10.3/sys/dev/vxge/vxge.c 281955 2015-04-24 23:26:44Z hiren $*/ 32221167Sgnn 33221167Sgnn#include <dev/vxge/vxge.h> 34221167Sgnn 35221167Sgnnstatic int vxge_pci_bd_no = -1; 36221167Sgnnstatic u32 vxge_drv_copyright = 0; 37221167Sgnnstatic u32 vxge_dev_ref_count = 0; 38221167Sgnnstatic u32 vxge_dev_req_reboot = 0; 39221167Sgnn 40221167Sgnnstatic int vpath_selector[VXGE_HAL_MAX_VIRTUAL_PATHS] = \ 41221167Sgnn{0, 1, 3, 3, 7, 7, 7, 7, 15, 15, 15, 15, 15, 15, 15, 15, 31}; 42221167Sgnn 43221167Sgnn/* 44221167Sgnn * vxge_probe 45221167Sgnn * Probes for x3100 devices 46221167Sgnn */ 47221167Sgnnint 48221167Sgnnvxge_probe(device_t ndev) 49221167Sgnn{ 50221167Sgnn int err = ENXIO; 51221167Sgnn 52221167Sgnn u16 pci_bd_no = 0; 53221167Sgnn u16 pci_vendor_id = 0; 54221167Sgnn u16 pci_device_id = 0; 55221167Sgnn 56221167Sgnn char adapter_name[64]; 57221167Sgnn 58221167Sgnn pci_vendor_id = pci_get_vendor(ndev); 59221167Sgnn if (pci_vendor_id != VXGE_PCI_VENDOR_ID) 60221167Sgnn goto _exit0; 61221167Sgnn 62221167Sgnn pci_device_id = pci_get_device(ndev); 63221167Sgnn 64221167Sgnn if (pci_device_id == VXGE_PCI_DEVICE_ID_TITAN_1) { 65221167Sgnn 66221167Sgnn pci_bd_no = (pci_get_bus(ndev) | pci_get_slot(ndev)); 67221167Sgnn 68221167Sgnn snprintf(adapter_name, sizeof(adapter_name), 69221167Sgnn VXGE_ADAPTER_NAME, pci_get_revid(ndev)); 70221167Sgnn device_set_desc_copy(ndev, adapter_name); 71221167Sgnn 72221167Sgnn if (!vxge_drv_copyright) { 73221167Sgnn device_printf(ndev, VXGE_COPYRIGHT); 74221167Sgnn vxge_drv_copyright = 1; 75221167Sgnn } 76221167Sgnn 77221167Sgnn if (vxge_dev_req_reboot == 0) { 78221167Sgnn vxge_pci_bd_no = pci_bd_no; 79221167Sgnn err = BUS_PROBE_DEFAULT; 80221167Sgnn } else { 81221167Sgnn if (pci_bd_no != vxge_pci_bd_no) { 82221167Sgnn vxge_pci_bd_no = pci_bd_no; 83221167Sgnn err = BUS_PROBE_DEFAULT; 84221167Sgnn } 85221167Sgnn } 86221167Sgnn } 87221167Sgnn 88221167Sgnn_exit0: 89221167Sgnn return (err); 90221167Sgnn} 91221167Sgnn 92221167Sgnn/* 93221167Sgnn * vxge_attach 94221167Sgnn * Connects driver to the system if probe was success @ndev handle 95221167Sgnn */ 96221167Sgnnint 97221167Sgnnvxge_attach(device_t ndev) 98221167Sgnn{ 99221167Sgnn int err = 0; 100221167Sgnn vxge_dev_t *vdev; 101221167Sgnn vxge_hal_device_t *hldev = NULL; 102221167Sgnn vxge_hal_device_attr_t device_attr; 103221167Sgnn vxge_free_resources_e error_level = VXGE_FREE_NONE; 104221167Sgnn 105221167Sgnn vxge_hal_status_e status = VXGE_HAL_OK; 106221167Sgnn 107221167Sgnn /* Get per-ndev buffer */ 108221167Sgnn vdev = (vxge_dev_t *) device_get_softc(ndev); 109221167Sgnn if (!vdev) 110221167Sgnn goto _exit0; 111221167Sgnn 112221167Sgnn bzero(vdev, sizeof(vxge_dev_t)); 113221167Sgnn 114221167Sgnn vdev->ndev = ndev; 115221167Sgnn strlcpy(vdev->ndev_name, "vxge", sizeof(vdev->ndev_name)); 116221167Sgnn 117221167Sgnn err = vxge_driver_config(vdev); 118221167Sgnn if (err != 0) 119221167Sgnn goto _exit0; 120221167Sgnn 121221167Sgnn /* Initialize HAL driver */ 122221167Sgnn status = vxge_driver_init(vdev); 123221167Sgnn if (status != VXGE_HAL_OK) { 124221167Sgnn device_printf(vdev->ndev, "Failed to initialize driver\n"); 125221167Sgnn goto _exit0; 126221167Sgnn } 127221167Sgnn /* Enable PCI bus-master */ 128221167Sgnn pci_enable_busmaster(ndev); 129221167Sgnn 130221167Sgnn /* Allocate resources */ 131221167Sgnn err = vxge_alloc_resources(vdev); 132221167Sgnn if (err != 0) { 133221167Sgnn device_printf(vdev->ndev, "resource allocation failed\n"); 134221167Sgnn goto _exit0; 135221167Sgnn } 136221167Sgnn 137221167Sgnn err = vxge_device_hw_info_get(vdev); 138221167Sgnn if (err != 0) { 139221167Sgnn error_level = VXGE_FREE_BAR2; 140221167Sgnn goto _exit0; 141221167Sgnn } 142221167Sgnn 143221167Sgnn /* Get firmware default values for Device Configuration */ 144221167Sgnn vxge_hal_device_config_default_get(vdev->device_config); 145221167Sgnn 146221167Sgnn /* Customize Device Configuration based on User request */ 147221167Sgnn vxge_vpath_config(vdev); 148221167Sgnn 149221167Sgnn /* Allocate ISR resources */ 150221167Sgnn err = vxge_alloc_isr_resources(vdev); 151221167Sgnn if (err != 0) { 152221167Sgnn error_level = VXGE_FREE_ISR_RESOURCE; 153221167Sgnn device_printf(vdev->ndev, "isr resource allocation failed\n"); 154221167Sgnn goto _exit0; 155221167Sgnn } 156221167Sgnn 157221167Sgnn /* HAL attributes */ 158221167Sgnn device_attr.bar0 = (u8 *) vdev->pdev->bar_info[0]; 159221167Sgnn device_attr.bar1 = (u8 *) vdev->pdev->bar_info[1]; 160221167Sgnn device_attr.bar2 = (u8 *) vdev->pdev->bar_info[2]; 161221167Sgnn device_attr.regh0 = (vxge_bus_res_t *) vdev->pdev->reg_map[0]; 162221167Sgnn device_attr.regh1 = (vxge_bus_res_t *) vdev->pdev->reg_map[1]; 163221167Sgnn device_attr.regh2 = (vxge_bus_res_t *) vdev->pdev->reg_map[2]; 164221167Sgnn device_attr.irqh = (pci_irq_h) vdev->config.isr_info[0].irq_handle; 165221167Sgnn device_attr.cfgh = vdev->pdev; 166221167Sgnn device_attr.pdev = vdev->pdev; 167221167Sgnn 168221167Sgnn /* Initialize HAL Device */ 169221167Sgnn status = vxge_hal_device_initialize((vxge_hal_device_h *) &hldev, 170221167Sgnn &device_attr, vdev->device_config); 171221167Sgnn if (status != VXGE_HAL_OK) { 172221167Sgnn error_level = VXGE_FREE_ISR_RESOURCE; 173221167Sgnn device_printf(vdev->ndev, "hal device initialization failed\n"); 174221167Sgnn goto _exit0; 175221167Sgnn } 176221167Sgnn 177221167Sgnn vdev->devh = hldev; 178221167Sgnn vxge_hal_device_private_set(hldev, vdev); 179221167Sgnn 180221167Sgnn if (vdev->is_privilaged) { 181221167Sgnn err = vxge_firmware_verify(vdev); 182221167Sgnn if (err != 0) { 183221167Sgnn vxge_dev_req_reboot = 1; 184221167Sgnn error_level = VXGE_FREE_TERMINATE_DEVICE; 185221167Sgnn goto _exit0; 186221167Sgnn } 187221167Sgnn } 188221167Sgnn 189221167Sgnn /* Allocate memory for vpath */ 190221167Sgnn vdev->vpaths = (vxge_vpath_t *) 191221167Sgnn vxge_mem_alloc(vdev->no_of_vpath * sizeof(vxge_vpath_t)); 192221167Sgnn 193221167Sgnn if (vdev->vpaths == NULL) { 194221167Sgnn error_level = VXGE_FREE_TERMINATE_DEVICE; 195221167Sgnn device_printf(vdev->ndev, "vpath memory allocation failed\n"); 196221167Sgnn goto _exit0; 197221167Sgnn } 198221167Sgnn 199221167Sgnn vdev->no_of_func = 1; 200221167Sgnn if (vdev->is_privilaged) { 201221167Sgnn 202221167Sgnn vxge_hal_func_mode_count(vdev->devh, 203221167Sgnn vdev->config.hw_info.function_mode, &vdev->no_of_func); 204221167Sgnn 205221167Sgnn vxge_bw_priority_config(vdev); 206221167Sgnn } 207221167Sgnn 208221167Sgnn /* Initialize mutexes */ 209221167Sgnn vxge_mutex_init(vdev); 210221167Sgnn 211221167Sgnn /* Initialize Media */ 212221167Sgnn vxge_media_init(vdev); 213221167Sgnn 214221167Sgnn err = vxge_ifp_setup(ndev); 215221167Sgnn if (err != 0) { 216221167Sgnn error_level = VXGE_FREE_MEDIA; 217221167Sgnn device_printf(vdev->ndev, "setting up interface failed\n"); 218221167Sgnn goto _exit0; 219221167Sgnn } 220221167Sgnn 221221167Sgnn err = vxge_isr_setup(vdev); 222221167Sgnn if (err != 0) { 223221167Sgnn error_level = VXGE_FREE_INTERFACE; 224221167Sgnn device_printf(vdev->ndev, 225221167Sgnn "failed to associate interrupt handler with device\n"); 226221167Sgnn goto _exit0; 227221167Sgnn } 228221167Sgnn vxge_device_hw_info_print(vdev); 229221167Sgnn vdev->is_active = TRUE; 230221167Sgnn 231221167Sgnn_exit0: 232221167Sgnn if (error_level) { 233221167Sgnn vxge_free_resources(ndev, error_level); 234221167Sgnn err = ENXIO; 235221167Sgnn } 236221167Sgnn 237221167Sgnn return (err); 238221167Sgnn} 239221167Sgnn 240221167Sgnn/* 241221167Sgnn * vxge_detach 242221167Sgnn * Detaches driver from the Kernel subsystem 243221167Sgnn */ 244221167Sgnnint 245221167Sgnnvxge_detach(device_t ndev) 246221167Sgnn{ 247221167Sgnn vxge_dev_t *vdev; 248221167Sgnn 249221167Sgnn vdev = (vxge_dev_t *) device_get_softc(ndev); 250221167Sgnn if (vdev->is_active) { 251221167Sgnn vdev->is_active = FALSE; 252221167Sgnn vxge_stop(vdev); 253221167Sgnn vxge_free_resources(ndev, VXGE_FREE_ALL); 254221167Sgnn } 255221167Sgnn 256221167Sgnn return (0); 257221167Sgnn} 258221167Sgnn 259221167Sgnn/* 260221167Sgnn * vxge_shutdown 261221167Sgnn * To shutdown device before system shutdown 262221167Sgnn */ 263221167Sgnnint 264221167Sgnnvxge_shutdown(device_t ndev) 265221167Sgnn{ 266221167Sgnn vxge_dev_t *vdev = (vxge_dev_t *) device_get_softc(ndev); 267221167Sgnn vxge_stop(vdev); 268221167Sgnn return (0); 269221167Sgnn} 270221167Sgnn 271221167Sgnn/* 272221167Sgnn * vxge_init 273221167Sgnn * Initialize the interface 274221167Sgnn */ 275221167Sgnnvoid 276221167Sgnnvxge_init(void *vdev_ptr) 277221167Sgnn{ 278221167Sgnn vxge_dev_t *vdev = (vxge_dev_t *) vdev_ptr; 279221167Sgnn 280221167Sgnn VXGE_DRV_LOCK(vdev); 281221167Sgnn vxge_init_locked(vdev); 282221167Sgnn VXGE_DRV_UNLOCK(vdev); 283221167Sgnn} 284221167Sgnn 285221167Sgnn/* 286221167Sgnn * vxge_init_locked 287221167Sgnn * Initialize the interface 288221167Sgnn */ 289221167Sgnnvoid 290221167Sgnnvxge_init_locked(vxge_dev_t *vdev) 291221167Sgnn{ 292221167Sgnn int i, err = EINVAL; 293221167Sgnn vxge_hal_device_t *hldev = vdev->devh; 294221167Sgnn vxge_hal_status_e status = VXGE_HAL_OK; 295221167Sgnn vxge_hal_vpath_h vpath_handle; 296221167Sgnn 297221167Sgnn ifnet_t ifp = vdev->ifp; 298221167Sgnn 299221167Sgnn /* If device is in running state, initializing is not required */ 300221167Sgnn if (ifp->if_drv_flags & IFF_DRV_RUNNING) 301221167Sgnn goto _exit0; 302221167Sgnn 303221167Sgnn VXGE_DRV_LOCK_ASSERT(vdev); 304221167Sgnn 305221167Sgnn /* Opening vpaths */ 306221167Sgnn err = vxge_vpath_open(vdev); 307221167Sgnn if (err != 0) 308221167Sgnn goto _exit1; 309221167Sgnn 310221167Sgnn if (vdev->config.rth_enable) { 311221167Sgnn status = vxge_rth_config(vdev); 312221167Sgnn if (status != VXGE_HAL_OK) 313221167Sgnn goto _exit1; 314221167Sgnn } 315221167Sgnn 316221167Sgnn for (i = 0; i < vdev->no_of_vpath; i++) { 317221167Sgnn vpath_handle = vxge_vpath_handle_get(vdev, i); 318221167Sgnn if (!vpath_handle) 319221167Sgnn continue; 320221167Sgnn 321221167Sgnn /* check initial mtu before enabling the device */ 322221167Sgnn status = vxge_hal_device_mtu_check(vpath_handle, ifp->if_mtu); 323221167Sgnn if (status != VXGE_HAL_OK) { 324221167Sgnn device_printf(vdev->ndev, 325221167Sgnn "invalid mtu size %ld specified\n", ifp->if_mtu); 326221167Sgnn goto _exit1; 327221167Sgnn } 328221167Sgnn 329221167Sgnn status = vxge_hal_vpath_mtu_set(vpath_handle, ifp->if_mtu); 330221167Sgnn if (status != VXGE_HAL_OK) { 331221167Sgnn device_printf(vdev->ndev, 332221167Sgnn "setting mtu in device failed\n"); 333221167Sgnn goto _exit1; 334221167Sgnn } 335221167Sgnn } 336221167Sgnn 337221167Sgnn /* Enable HAL device */ 338221167Sgnn status = vxge_hal_device_enable(hldev); 339221167Sgnn if (status != VXGE_HAL_OK) { 340221167Sgnn device_printf(vdev->ndev, "failed to enable device\n"); 341221167Sgnn goto _exit1; 342221167Sgnn } 343221167Sgnn 344221167Sgnn if (vdev->config.intr_mode == VXGE_HAL_INTR_MODE_MSIX) 345221167Sgnn vxge_msix_enable(vdev); 346221167Sgnn 347221167Sgnn /* Checksum capability */ 348221167Sgnn ifp->if_hwassist = 0; 349221167Sgnn if (ifp->if_capenable & IFCAP_TXCSUM) 350221167Sgnn ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP); 351221167Sgnn 352221167Sgnn if (ifp->if_capenable & IFCAP_TSO4) 353221167Sgnn ifp->if_hwassist |= CSUM_TSO; 354221167Sgnn 355221167Sgnn for (i = 0; i < vdev->no_of_vpath; i++) { 356221167Sgnn vpath_handle = vxge_vpath_handle_get(vdev, i); 357221167Sgnn if (!vpath_handle) 358221167Sgnn continue; 359221167Sgnn 360221389Sgnn /* Enabling mcast for all vpath */ 361221389Sgnn vxge_hal_vpath_mcast_enable(vpath_handle); 362221389Sgnn 363221167Sgnn /* Enabling bcast for all vpath */ 364221167Sgnn status = vxge_hal_vpath_bcast_enable(vpath_handle); 365221167Sgnn if (status != VXGE_HAL_OK) 366221167Sgnn device_printf(vdev->ndev, 367221167Sgnn "can't enable bcast on vpath (%d)\n", i); 368221167Sgnn } 369221167Sgnn 370221167Sgnn /* Enable interrupts */ 371221167Sgnn vxge_hal_device_intr_enable(vdev->devh); 372221167Sgnn 373221167Sgnn for (i = 0; i < vdev->no_of_vpath; i++) { 374221167Sgnn vpath_handle = vxge_vpath_handle_get(vdev, i); 375221167Sgnn if (!vpath_handle) 376221167Sgnn continue; 377221167Sgnn 378221167Sgnn bzero(&(vdev->vpaths[i].driver_stats), 379221167Sgnn sizeof(vxge_drv_stats_t)); 380221167Sgnn status = vxge_hal_vpath_enable(vpath_handle); 381221167Sgnn if (status != VXGE_HAL_OK) 382221167Sgnn goto _exit2; 383221167Sgnn } 384221167Sgnn 385221167Sgnn vxge_os_mdelay(1000); 386221167Sgnn 387221167Sgnn /* Device is initialized */ 388221167Sgnn vdev->is_initialized = TRUE; 389221167Sgnn 390221167Sgnn /* Now inform the stack we're ready */ 391221167Sgnn ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 392221167Sgnn ifp->if_drv_flags |= IFF_DRV_RUNNING; 393221167Sgnn 394221167Sgnn goto _exit0; 395221167Sgnn 396221167Sgnn_exit2: 397221167Sgnn vxge_hal_device_intr_disable(vdev->devh); 398221167Sgnn vxge_hal_device_disable(hldev); 399221167Sgnn 400221167Sgnn_exit1: 401221167Sgnn vxge_vpath_close(vdev); 402221167Sgnn 403221167Sgnn_exit0: 404221167Sgnn return; 405221167Sgnn} 406221167Sgnn 407221167Sgnn/* 408221167Sgnn * vxge_driver_init 409221167Sgnn * Initializes HAL driver 410221167Sgnn */ 411221167Sgnnvxge_hal_status_e 412221167Sgnnvxge_driver_init(vxge_dev_t *vdev) 413221167Sgnn{ 414221167Sgnn vxge_hal_uld_cbs_t uld_callbacks; 415221167Sgnn vxge_hal_driver_config_t driver_config; 416221167Sgnn vxge_hal_status_e status = VXGE_HAL_OK; 417221167Sgnn 418221167Sgnn /* Initialize HAL driver */ 419221167Sgnn if (!vxge_dev_ref_count) { 420221167Sgnn bzero(&uld_callbacks, sizeof(vxge_hal_uld_cbs_t)); 421221167Sgnn bzero(&driver_config, sizeof(vxge_hal_driver_config_t)); 422221167Sgnn 423221167Sgnn uld_callbacks.link_up = vxge_link_up; 424221167Sgnn uld_callbacks.link_down = vxge_link_down; 425221167Sgnn uld_callbacks.crit_err = vxge_crit_error; 426221167Sgnn uld_callbacks.sched_timer = NULL; 427221167Sgnn uld_callbacks.xpak_alarm_log = NULL; 428221167Sgnn 429221167Sgnn status = vxge_hal_driver_initialize(&driver_config, 430221167Sgnn &uld_callbacks); 431221167Sgnn if (status != VXGE_HAL_OK) { 432221167Sgnn device_printf(vdev->ndev, 433221167Sgnn "failed to initialize driver\n"); 434221167Sgnn goto _exit0; 435221167Sgnn } 436221167Sgnn } 437221167Sgnn vxge_hal_driver_debug_set(VXGE_TRACE); 438221167Sgnn vxge_dev_ref_count++; 439221167Sgnn 440221167Sgnn_exit0: 441221167Sgnn return (status); 442221167Sgnn} 443221167Sgnn 444221167Sgnn/* 445221167Sgnn * vxge_driver_config 446221167Sgnn */ 447221167Sgnnint 448221167Sgnnvxge_driver_config(vxge_dev_t *vdev) 449221167Sgnn{ 450221167Sgnn int i, err = 0; 451221167Sgnn char temp_buffer[30]; 452221167Sgnn 453221167Sgnn vxge_bw_info_t bw_info; 454221167Sgnn 455221167Sgnn VXGE_GET_PARAM("hint.vxge.0.no_of_vpath", vdev->config, 456221167Sgnn no_of_vpath, VXGE_DEFAULT_USER_HARDCODED); 457221167Sgnn 458221167Sgnn if (vdev->config.no_of_vpath == VXGE_DEFAULT_USER_HARDCODED) 459221167Sgnn vdev->config.no_of_vpath = mp_ncpus; 460221167Sgnn 461221167Sgnn if (vdev->config.no_of_vpath <= 0) { 462221167Sgnn err = EINVAL; 463221167Sgnn device_printf(vdev->ndev, 464221167Sgnn "Failed to load driver, \ 465221167Sgnn invalid config : \'no_of_vpath\'\n"); 466221167Sgnn goto _exit0; 467221167Sgnn } 468221167Sgnn 469221167Sgnn VXGE_GET_PARAM("hint.vxge.0.intr_coalesce", vdev->config, 470221167Sgnn intr_coalesce, VXGE_DEFAULT_CONFIG_DISABLE); 471221167Sgnn 472221167Sgnn VXGE_GET_PARAM("hint.vxge.0.rth_enable", vdev->config, 473221167Sgnn rth_enable, VXGE_DEFAULT_CONFIG_ENABLE); 474221167Sgnn 475221167Sgnn VXGE_GET_PARAM("hint.vxge.0.rth_bkt_sz", vdev->config, 476221167Sgnn rth_bkt_sz, VXGE_DEFAULT_RTH_BUCKET_SIZE); 477221167Sgnn 478221167Sgnn VXGE_GET_PARAM("hint.vxge.0.lro_enable", vdev->config, 479221167Sgnn lro_enable, VXGE_DEFAULT_CONFIG_ENABLE); 480221167Sgnn 481221167Sgnn VXGE_GET_PARAM("hint.vxge.0.tso_enable", vdev->config, 482221167Sgnn tso_enable, VXGE_DEFAULT_CONFIG_ENABLE); 483221167Sgnn 484221167Sgnn VXGE_GET_PARAM("hint.vxge.0.tx_steering", vdev->config, 485221167Sgnn tx_steering, VXGE_DEFAULT_CONFIG_DISABLE); 486221167Sgnn 487221167Sgnn VXGE_GET_PARAM("hint.vxge.0.msix_enable", vdev->config, 488221167Sgnn intr_mode, VXGE_HAL_INTR_MODE_MSIX); 489221167Sgnn 490221167Sgnn VXGE_GET_PARAM("hint.vxge.0.ifqmaxlen", vdev->config, 491221167Sgnn ifq_maxlen, VXGE_DEFAULT_CONFIG_IFQ_MAXLEN); 492221167Sgnn 493221167Sgnn VXGE_GET_PARAM("hint.vxge.0.port_mode", vdev->config, 494221167Sgnn port_mode, VXGE_DEFAULT_CONFIG_VALUE); 495221167Sgnn 496221167Sgnn if (vdev->config.port_mode == VXGE_DEFAULT_USER_HARDCODED) 497221167Sgnn vdev->config.port_mode = VXGE_DEFAULT_CONFIG_VALUE; 498221167Sgnn 499221167Sgnn VXGE_GET_PARAM("hint.vxge.0.l2_switch", vdev->config, 500221167Sgnn l2_switch, VXGE_DEFAULT_CONFIG_VALUE); 501221167Sgnn 502221167Sgnn if (vdev->config.l2_switch == VXGE_DEFAULT_USER_HARDCODED) 503221167Sgnn vdev->config.l2_switch = VXGE_DEFAULT_CONFIG_VALUE; 504221167Sgnn 505221167Sgnn VXGE_GET_PARAM("hint.vxge.0.fw_upgrade", vdev->config, 506221167Sgnn fw_option, VXGE_FW_UPGRADE_ALL); 507221167Sgnn 508221167Sgnn VXGE_GET_PARAM("hint.vxge.0.low_latency", vdev->config, 509221167Sgnn low_latency, VXGE_DEFAULT_CONFIG_DISABLE); 510221167Sgnn 511221167Sgnn VXGE_GET_PARAM("hint.vxge.0.func_mode", vdev->config, 512221167Sgnn function_mode, VXGE_DEFAULT_CONFIG_VALUE); 513221167Sgnn 514221167Sgnn if (vdev->config.function_mode == VXGE_DEFAULT_USER_HARDCODED) 515221167Sgnn vdev->config.function_mode = VXGE_DEFAULT_CONFIG_VALUE; 516221167Sgnn 517221167Sgnn if (!(is_multi_func(vdev->config.function_mode) || 518221167Sgnn is_single_func(vdev->config.function_mode))) 519221167Sgnn vdev->config.function_mode = VXGE_DEFAULT_CONFIG_VALUE; 520221167Sgnn 521221167Sgnn for (i = 0; i < VXGE_HAL_MAX_FUNCTIONS; i++) { 522221167Sgnn 523221167Sgnn bw_info.func_id = i; 524221167Sgnn 525221167Sgnn sprintf(temp_buffer, "hint.vxge.0.bandwidth_%d", i); 526221167Sgnn VXGE_GET_PARAM(temp_buffer, bw_info, 527221167Sgnn bandwidth, VXGE_DEFAULT_USER_HARDCODED); 528221167Sgnn 529221167Sgnn if (bw_info.bandwidth == VXGE_DEFAULT_USER_HARDCODED) 530221167Sgnn bw_info.bandwidth = VXGE_HAL_VPATH_BW_LIMIT_DEFAULT; 531221167Sgnn 532221167Sgnn sprintf(temp_buffer, "hint.vxge.0.priority_%d", i); 533221167Sgnn VXGE_GET_PARAM(temp_buffer, bw_info, 534221167Sgnn priority, VXGE_DEFAULT_USER_HARDCODED); 535221167Sgnn 536221167Sgnn if (bw_info.priority == VXGE_DEFAULT_USER_HARDCODED) 537221167Sgnn bw_info.priority = VXGE_HAL_VPATH_PRIORITY_DEFAULT; 538221167Sgnn 539221167Sgnn vxge_os_memcpy(&vdev->config.bw_info[i], &bw_info, 540221167Sgnn sizeof(vxge_bw_info_t)); 541221167Sgnn } 542221167Sgnn 543221167Sgnn_exit0: 544221167Sgnn return (err); 545221167Sgnn} 546221167Sgnn 547221167Sgnn/* 548221167Sgnn * vxge_stop 549221167Sgnn */ 550221167Sgnnvoid 551221167Sgnnvxge_stop(vxge_dev_t *vdev) 552221167Sgnn{ 553221167Sgnn VXGE_DRV_LOCK(vdev); 554221167Sgnn vxge_stop_locked(vdev); 555221167Sgnn VXGE_DRV_UNLOCK(vdev); 556221167Sgnn} 557221167Sgnn 558221167Sgnn/* 559221167Sgnn * vxge_stop_locked 560221167Sgnn * Common code for both stop and part of reset. 561221167Sgnn * disables device, interrupts and closes vpaths handle 562221167Sgnn */ 563221167Sgnnvoid 564221167Sgnnvxge_stop_locked(vxge_dev_t *vdev) 565221167Sgnn{ 566221167Sgnn u64 adapter_status = 0; 567221167Sgnn vxge_hal_status_e status; 568221167Sgnn vxge_hal_device_t *hldev = vdev->devh; 569221167Sgnn ifnet_t ifp = vdev->ifp; 570221167Sgnn 571221167Sgnn VXGE_DRV_LOCK_ASSERT(vdev); 572221167Sgnn 573221167Sgnn /* If device is not in "Running" state, return */ 574221167Sgnn if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) 575221167Sgnn return; 576221167Sgnn 577221167Sgnn /* Set appropriate flags */ 578221167Sgnn vdev->is_initialized = FALSE; 579221167Sgnn hldev->link_state = VXGE_HAL_LINK_NONE; 580221167Sgnn ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); 581221167Sgnn if_link_state_change(ifp, LINK_STATE_DOWN); 582221167Sgnn 583221167Sgnn /* Disable interrupts */ 584221167Sgnn vxge_hal_device_intr_disable(hldev); 585221167Sgnn 586221167Sgnn /* Disable HAL device */ 587221167Sgnn status = vxge_hal_device_disable(hldev); 588221167Sgnn if (status != VXGE_HAL_OK) { 589221167Sgnn vxge_hal_device_status(hldev, &adapter_status); 590221167Sgnn device_printf(vdev->ndev, 591221167Sgnn "adapter status: 0x%llx\n", adapter_status); 592221167Sgnn } 593221167Sgnn 594221167Sgnn /* reset vpaths */ 595221167Sgnn vxge_vpath_reset(vdev); 596221167Sgnn 597221167Sgnn vxge_os_mdelay(1000); 598221167Sgnn 599221167Sgnn /* Close Vpaths */ 600221167Sgnn vxge_vpath_close(vdev); 601221167Sgnn} 602221167Sgnn 603221167Sgnnvoid 604221167Sgnnvxge_send(ifnet_t ifp) 605221167Sgnn{ 606221167Sgnn vxge_vpath_t *vpath; 607221167Sgnn vxge_dev_t *vdev = (vxge_dev_t *) ifp->if_softc; 608221167Sgnn 609221167Sgnn vpath = &(vdev->vpaths[0]); 610221167Sgnn 611221167Sgnn if (ifp->if_drv_flags & IFF_DRV_RUNNING) { 612221167Sgnn if (VXGE_TX_TRYLOCK(vpath)) { 613221167Sgnn vxge_send_locked(ifp, vpath); 614221167Sgnn VXGE_TX_UNLOCK(vpath); 615221167Sgnn } 616221167Sgnn } 617221167Sgnn} 618221167Sgnn 619221167Sgnnstatic inline void 620221167Sgnnvxge_send_locked(ifnet_t ifp, vxge_vpath_t *vpath) 621221167Sgnn{ 622221167Sgnn mbuf_t m_head = NULL; 623221167Sgnn vxge_dev_t *vdev = vpath->vdev; 624221167Sgnn 625221167Sgnn VXGE_TX_LOCK_ASSERT(vpath); 626221167Sgnn 627221167Sgnn if ((!vdev->is_initialized) || 628221167Sgnn ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != 629221167Sgnn IFF_DRV_RUNNING)) 630221167Sgnn return; 631221167Sgnn 632221167Sgnn while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) { 633221167Sgnn IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head); 634221167Sgnn if (m_head == NULL) 635221167Sgnn break; 636221167Sgnn 637221167Sgnn if (vxge_xmit(ifp, vpath, &m_head)) { 638221167Sgnn if (m_head == NULL) 639221167Sgnn break; 640221167Sgnn 641221167Sgnn ifp->if_drv_flags |= IFF_DRV_OACTIVE; 642221167Sgnn IFQ_DRV_PREPEND(&ifp->if_snd, m_head); 643221167Sgnn VXGE_DRV_STATS(vpath, tx_again); 644221167Sgnn break; 645221167Sgnn } 646221167Sgnn /* Send a copy of the frame to the BPF listener */ 647221167Sgnn ETHER_BPF_MTAP(ifp, m_head); 648221167Sgnn } 649221167Sgnn} 650221167Sgnn 651221167Sgnn#if __FreeBSD_version >= 800000 652221167Sgnn 653221167Sgnnint 654221167Sgnnvxge_mq_send(ifnet_t ifp, mbuf_t m_head) 655221167Sgnn{ 656221167Sgnn int i = 0, err = 0; 657221167Sgnn 658221167Sgnn vxge_vpath_t *vpath; 659221167Sgnn vxge_dev_t *vdev = (vxge_dev_t *) ifp->if_softc; 660221167Sgnn 661221167Sgnn if (vdev->config.tx_steering) { 662221167Sgnn i = vxge_vpath_get(vdev, m_head); 663281955Shiren } else if (M_HASHTYPE_GET(m_head) != M_HASHTYPE_NONE) { 664221167Sgnn i = m_head->m_pkthdr.flowid % vdev->no_of_vpath; 665221167Sgnn } 666221167Sgnn 667221167Sgnn vpath = &(vdev->vpaths[i]); 668221167Sgnn if (VXGE_TX_TRYLOCK(vpath)) { 669221167Sgnn err = vxge_mq_send_locked(ifp, vpath, m_head); 670221167Sgnn VXGE_TX_UNLOCK(vpath); 671221167Sgnn } else 672221167Sgnn err = drbr_enqueue(ifp, vpath->br, m_head); 673221167Sgnn 674221167Sgnn return (err); 675221167Sgnn} 676221167Sgnn 677221167Sgnnstatic inline int 678221167Sgnnvxge_mq_send_locked(ifnet_t ifp, vxge_vpath_t *vpath, mbuf_t m_head) 679221167Sgnn{ 680221167Sgnn int err = 0; 681221167Sgnn mbuf_t next = NULL; 682221167Sgnn vxge_dev_t *vdev = vpath->vdev; 683221167Sgnn 684221167Sgnn VXGE_TX_LOCK_ASSERT(vpath); 685221167Sgnn 686221167Sgnn if ((!vdev->is_initialized) || 687221167Sgnn ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != 688221167Sgnn IFF_DRV_RUNNING)) { 689221167Sgnn err = drbr_enqueue(ifp, vpath->br, m_head); 690221167Sgnn goto _exit0; 691221167Sgnn } 692221167Sgnn if (m_head == NULL) { 693221167Sgnn next = drbr_dequeue(ifp, vpath->br); 694221167Sgnn } else if (drbr_needs_enqueue(ifp, vpath->br)) { 695221167Sgnn if ((err = drbr_enqueue(ifp, vpath->br, m_head)) != 0) 696221167Sgnn goto _exit0; 697221167Sgnn next = drbr_dequeue(ifp, vpath->br); 698221167Sgnn } else 699221167Sgnn next = m_head; 700221167Sgnn 701221167Sgnn /* Process the queue */ 702221167Sgnn while (next != NULL) { 703221167Sgnn if ((err = vxge_xmit(ifp, vpath, &next)) != 0) { 704221167Sgnn if (next == NULL) 705221167Sgnn break; 706221167Sgnn 707221167Sgnn ifp->if_drv_flags |= IFF_DRV_OACTIVE; 708221167Sgnn err = drbr_enqueue(ifp, vpath->br, next); 709221167Sgnn VXGE_DRV_STATS(vpath, tx_again); 710221167Sgnn break; 711221167Sgnn } 712241037Sglebius ifp->if_obytes += next->m_pkthdr.len; 713241037Sglebius if (next->m_flags & M_MCAST) 714241037Sglebius ifp->if_omcasts++; 715221167Sgnn 716221167Sgnn /* Send a copy of the frame to the BPF listener */ 717221167Sgnn ETHER_BPF_MTAP(ifp, next); 718221167Sgnn if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) 719221167Sgnn break; 720221167Sgnn 721221167Sgnn next = drbr_dequeue(ifp, vpath->br); 722221167Sgnn } 723221167Sgnn 724221167Sgnn_exit0: 725221167Sgnn return (err); 726221167Sgnn} 727221167Sgnn 728221167Sgnnvoid 729221167Sgnnvxge_mq_qflush(ifnet_t ifp) 730221167Sgnn{ 731221167Sgnn int i; 732221167Sgnn mbuf_t m_head; 733221167Sgnn vxge_vpath_t *vpath; 734221167Sgnn 735221167Sgnn vxge_dev_t *vdev = (vxge_dev_t *) ifp->if_softc; 736221167Sgnn 737221167Sgnn for (i = 0; i < vdev->no_of_vpath; i++) { 738221167Sgnn vpath = &(vdev->vpaths[i]); 739221167Sgnn if (!vpath->handle) 740221167Sgnn continue; 741221167Sgnn 742221167Sgnn VXGE_TX_LOCK(vpath); 743221167Sgnn while ((m_head = buf_ring_dequeue_sc(vpath->br)) != NULL) 744221167Sgnn vxge_free_packet(m_head); 745221167Sgnn 746221167Sgnn VXGE_TX_UNLOCK(vpath); 747221167Sgnn } 748221167Sgnn if_qflush(ifp); 749221167Sgnn} 750221167Sgnn#endif 751221167Sgnn 752221167Sgnnstatic inline int 753221167Sgnnvxge_xmit(ifnet_t ifp, vxge_vpath_t *vpath, mbuf_t *m_headp) 754221167Sgnn{ 755221167Sgnn int err, num_segs = 0; 756221167Sgnn u32 txdl_avail, dma_index, tagged = 0; 757221167Sgnn 758221167Sgnn dma_addr_t dma_addr; 759221167Sgnn bus_size_t dma_sizes; 760221167Sgnn 761221167Sgnn void *dtr_priv; 762221167Sgnn vxge_txdl_priv_t *txdl_priv; 763221167Sgnn vxge_hal_txdl_h txdlh; 764221167Sgnn vxge_hal_status_e status; 765221167Sgnn vxge_dev_t *vdev = vpath->vdev; 766221167Sgnn 767221167Sgnn VXGE_DRV_STATS(vpath, tx_xmit); 768221167Sgnn 769221167Sgnn txdl_avail = vxge_hal_fifo_free_txdl_count_get(vpath->handle); 770221167Sgnn if (txdl_avail < VXGE_TX_LOW_THRESHOLD) { 771221167Sgnn 772221167Sgnn VXGE_DRV_STATS(vpath, tx_low_dtr_cnt); 773221167Sgnn err = ENOBUFS; 774221167Sgnn goto _exit0; 775221167Sgnn } 776221167Sgnn 777221167Sgnn /* Reserve descriptors */ 778221167Sgnn status = vxge_hal_fifo_txdl_reserve(vpath->handle, &txdlh, &dtr_priv); 779221167Sgnn if (status != VXGE_HAL_OK) { 780221167Sgnn VXGE_DRV_STATS(vpath, tx_reserve_failed); 781221167Sgnn err = ENOBUFS; 782221167Sgnn goto _exit0; 783221167Sgnn } 784221167Sgnn 785221167Sgnn /* Update Tx private structure for this descriptor */ 786221167Sgnn txdl_priv = (vxge_txdl_priv_t *) dtr_priv; 787221167Sgnn 788221167Sgnn /* 789221167Sgnn * Map the packet for DMA. 790221167Sgnn * Returns number of segments through num_segs. 791221167Sgnn */ 792221167Sgnn err = vxge_dma_mbuf_coalesce(vpath->dma_tag_tx, txdl_priv->dma_map, 793221167Sgnn m_headp, txdl_priv->dma_buffers, &num_segs); 794221167Sgnn 795221167Sgnn if (vpath->driver_stats.tx_max_frags < num_segs) 796221167Sgnn vpath->driver_stats.tx_max_frags = num_segs; 797221167Sgnn 798221167Sgnn if (err == ENOMEM) { 799221167Sgnn VXGE_DRV_STATS(vpath, tx_no_dma_setup); 800221167Sgnn vxge_hal_fifo_txdl_free(vpath->handle, txdlh); 801221167Sgnn goto _exit0; 802221167Sgnn } else if (err != 0) { 803221167Sgnn vxge_free_packet(*m_headp); 804221167Sgnn VXGE_DRV_STATS(vpath, tx_no_dma_setup); 805221167Sgnn vxge_hal_fifo_txdl_free(vpath->handle, txdlh); 806221167Sgnn goto _exit0; 807221167Sgnn } 808221167Sgnn 809221167Sgnn txdl_priv->mbuf_pkt = *m_headp; 810221167Sgnn 811221167Sgnn /* Set VLAN tag in descriptor only if this packet has it */ 812221167Sgnn if ((*m_headp)->m_flags & M_VLANTAG) 813221167Sgnn vxge_hal_fifo_txdl_vlan_set(txdlh, 814221167Sgnn (*m_headp)->m_pkthdr.ether_vtag); 815221167Sgnn 816221167Sgnn /* Set descriptor buffer for header and each fragment/segment */ 817221167Sgnn for (dma_index = 0; dma_index < num_segs; dma_index++) { 818221167Sgnn 819221167Sgnn dma_sizes = txdl_priv->dma_buffers[dma_index].ds_len; 820221167Sgnn dma_addr = htole64(txdl_priv->dma_buffers[dma_index].ds_addr); 821221167Sgnn 822221167Sgnn vxge_hal_fifo_txdl_buffer_set(vpath->handle, txdlh, dma_index, 823221167Sgnn dma_addr, dma_sizes); 824221167Sgnn } 825221167Sgnn 826221167Sgnn /* Pre-write Sync of mapping */ 827221167Sgnn bus_dmamap_sync(vpath->dma_tag_tx, txdl_priv->dma_map, 828221167Sgnn BUS_DMASYNC_PREWRITE); 829221167Sgnn 830221167Sgnn if ((*m_headp)->m_pkthdr.csum_flags & CSUM_TSO) { 831221167Sgnn if ((*m_headp)->m_pkthdr.tso_segsz) { 832221167Sgnn VXGE_DRV_STATS(vpath, tx_tso); 833221167Sgnn vxge_hal_fifo_txdl_lso_set(txdlh, 834221167Sgnn VXGE_HAL_FIFO_LSO_FRM_ENCAP_AUTO, 835221167Sgnn (*m_headp)->m_pkthdr.tso_segsz); 836221167Sgnn } 837221167Sgnn } 838221167Sgnn 839221167Sgnn /* Checksum */ 840221167Sgnn if (ifp->if_hwassist > 0) { 841221167Sgnn vxge_hal_fifo_txdl_cksum_set_bits(txdlh, 842221167Sgnn VXGE_HAL_FIFO_TXD_TX_CKO_IPV4_EN | 843221167Sgnn VXGE_HAL_FIFO_TXD_TX_CKO_TCP_EN | 844221167Sgnn VXGE_HAL_FIFO_TXD_TX_CKO_UDP_EN); 845221167Sgnn } 846221167Sgnn 847221167Sgnn if ((vxge_hal_device_check_id(vdev->devh) == VXGE_HAL_CARD_TITAN_1A) && 848221167Sgnn (vdev->hw_fw_version >= VXGE_FW_VERSION(1, 8, 0))) 849221167Sgnn tagged = 1; 850221167Sgnn 851221167Sgnn vxge_hal_fifo_txdl_post(vpath->handle, txdlh, tagged); 852221167Sgnn VXGE_DRV_STATS(vpath, tx_posted); 853221167Sgnn 854221167Sgnn_exit0: 855221167Sgnn return (err); 856221167Sgnn} 857221167Sgnn 858221167Sgnn/* 859221167Sgnn * vxge_tx_replenish 860221167Sgnn * Allocate buffers and set them into descriptors for later use 861221167Sgnn */ 862221167Sgnn/* ARGSUSED */ 863221167Sgnnvxge_hal_status_e 864221167Sgnnvxge_tx_replenish(vxge_hal_vpath_h vpath_handle, vxge_hal_txdl_h txdlh, 865221167Sgnn void *dtr_priv, u32 dtr_index, void *userdata, vxge_hal_reopen_e reopen) 866221167Sgnn{ 867221167Sgnn int err = 0; 868221167Sgnn 869221167Sgnn vxge_vpath_t *vpath = (vxge_vpath_t *) userdata; 870221167Sgnn vxge_txdl_priv_t *txdl_priv = (vxge_txdl_priv_t *) dtr_priv; 871221167Sgnn 872221167Sgnn err = bus_dmamap_create(vpath->dma_tag_tx, BUS_DMA_NOWAIT, 873221167Sgnn &txdl_priv->dma_map); 874221167Sgnn 875221167Sgnn return ((err == 0) ? VXGE_HAL_OK : VXGE_HAL_FAIL); 876221167Sgnn} 877221167Sgnn 878221167Sgnn/* 879221167Sgnn * vxge_tx_compl 880221167Sgnn * If the interrupt is due to Tx completion, free the sent buffer 881221167Sgnn */ 882221167Sgnnvxge_hal_status_e 883221167Sgnnvxge_tx_compl(vxge_hal_vpath_h vpath_handle, vxge_hal_txdl_h txdlh, 884221167Sgnn void *dtr_priv, vxge_hal_fifo_tcode_e t_code, void *userdata) 885221167Sgnn{ 886221167Sgnn vxge_hal_status_e status = VXGE_HAL_OK; 887221167Sgnn 888221167Sgnn vxge_txdl_priv_t *txdl_priv; 889221167Sgnn vxge_vpath_t *vpath = (vxge_vpath_t *) userdata; 890221167Sgnn vxge_dev_t *vdev = vpath->vdev; 891221167Sgnn 892221167Sgnn ifnet_t ifp = vdev->ifp; 893221167Sgnn 894221167Sgnn VXGE_TX_LOCK(vpath); 895221167Sgnn 896221167Sgnn /* 897221167Sgnn * For each completed descriptor 898221167Sgnn * Get private structure, free buffer, do unmapping, and free descriptor 899221167Sgnn */ 900221167Sgnn 901221167Sgnn do { 902221167Sgnn VXGE_DRV_STATS(vpath, tx_compl); 903221167Sgnn if (t_code != VXGE_HAL_FIFO_T_CODE_OK) { 904221167Sgnn device_printf(vdev->ndev, "tx transfer code %d\n", 905221167Sgnn t_code); 906221167Sgnn 907221167Sgnn ifp->if_oerrors++; 908221167Sgnn VXGE_DRV_STATS(vpath, tx_tcode); 909221167Sgnn vxge_hal_fifo_handle_tcode(vpath_handle, txdlh, t_code); 910221167Sgnn } 911221167Sgnn ifp->if_opackets++; 912221167Sgnn txdl_priv = (vxge_txdl_priv_t *) dtr_priv; 913221167Sgnn 914221167Sgnn bus_dmamap_unload(vpath->dma_tag_tx, txdl_priv->dma_map); 915221167Sgnn 916221167Sgnn vxge_free_packet(txdl_priv->mbuf_pkt); 917221167Sgnn vxge_hal_fifo_txdl_free(vpath->handle, txdlh); 918221167Sgnn 919221167Sgnn } while (vxge_hal_fifo_txdl_next_completed(vpath_handle, &txdlh, 920221167Sgnn &dtr_priv, &t_code) == VXGE_HAL_OK); 921221167Sgnn 922221167Sgnn 923221167Sgnn ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 924221167Sgnn VXGE_TX_UNLOCK(vpath); 925221167Sgnn 926221167Sgnn return (status); 927221167Sgnn} 928221167Sgnn 929221167Sgnn/* ARGSUSED */ 930221167Sgnnvoid 931221167Sgnnvxge_tx_term(vxge_hal_vpath_h vpath_handle, vxge_hal_txdl_h txdlh, 932221167Sgnn void *dtr_priv, vxge_hal_txdl_state_e state, 933221167Sgnn void *userdata, vxge_hal_reopen_e reopen) 934221167Sgnn{ 935221167Sgnn vxge_vpath_t *vpath = (vxge_vpath_t *) userdata; 936221167Sgnn vxge_txdl_priv_t *txdl_priv = (vxge_txdl_priv_t *) dtr_priv; 937221167Sgnn 938221167Sgnn if (state != VXGE_HAL_TXDL_STATE_POSTED) 939221167Sgnn return; 940221167Sgnn 941221167Sgnn if (txdl_priv != NULL) { 942221167Sgnn bus_dmamap_sync(vpath->dma_tag_tx, txdl_priv->dma_map, 943221167Sgnn BUS_DMASYNC_POSTWRITE); 944221167Sgnn 945221167Sgnn bus_dmamap_unload(vpath->dma_tag_tx, txdl_priv->dma_map); 946221167Sgnn bus_dmamap_destroy(vpath->dma_tag_tx, txdl_priv->dma_map); 947221167Sgnn vxge_free_packet(txdl_priv->mbuf_pkt); 948221167Sgnn } 949221167Sgnn 950221167Sgnn /* Free the descriptor */ 951221167Sgnn vxge_hal_fifo_txdl_free(vpath->handle, txdlh); 952221167Sgnn} 953221167Sgnn 954221167Sgnn/* 955221167Sgnn * vxge_rx_replenish 956221167Sgnn * Allocate buffers and set them into descriptors for later use 957221167Sgnn */ 958221167Sgnn/* ARGSUSED */ 959221167Sgnnvxge_hal_status_e 960221167Sgnnvxge_rx_replenish(vxge_hal_vpath_h vpath_handle, vxge_hal_rxd_h rxdh, 961221167Sgnn void *dtr_priv, u32 dtr_index, void *userdata, vxge_hal_reopen_e reopen) 962221167Sgnn{ 963221167Sgnn int err = 0; 964221167Sgnn vxge_hal_status_e status = VXGE_HAL_OK; 965221167Sgnn 966221167Sgnn vxge_vpath_t *vpath = (vxge_vpath_t *) userdata; 967221167Sgnn vxge_rxd_priv_t *rxd_priv = (vxge_rxd_priv_t *) dtr_priv; 968221167Sgnn 969221167Sgnn /* Create DMA map for these descriptors */ 970221167Sgnn err = bus_dmamap_create(vpath->dma_tag_rx, BUS_DMA_NOWAIT, 971221167Sgnn &rxd_priv->dma_map); 972221167Sgnn if (err == 0) { 973221167Sgnn if (vxge_rx_rxd_1b_set(vpath, rxdh, dtr_priv)) { 974221167Sgnn bus_dmamap_destroy(vpath->dma_tag_rx, 975221167Sgnn rxd_priv->dma_map); 976221167Sgnn status = VXGE_HAL_FAIL; 977221167Sgnn } 978221167Sgnn } 979221167Sgnn 980221167Sgnn return (status); 981221167Sgnn} 982221167Sgnn 983221167Sgnn/* 984221167Sgnn * vxge_rx_compl 985221167Sgnn */ 986221167Sgnnvxge_hal_status_e 987221167Sgnnvxge_rx_compl(vxge_hal_vpath_h vpath_handle, vxge_hal_rxd_h rxdh, 988221167Sgnn void *dtr_priv, u8 t_code, void *userdata) 989221167Sgnn{ 990221167Sgnn mbuf_t mbuf_up; 991221167Sgnn 992221167Sgnn vxge_rxd_priv_t *rxd_priv; 993221167Sgnn vxge_hal_ring_rxd_info_t ext_info; 994221167Sgnn vxge_hal_status_e status = VXGE_HAL_OK; 995221167Sgnn 996221167Sgnn vxge_vpath_t *vpath = (vxge_vpath_t *) userdata; 997221167Sgnn vxge_dev_t *vdev = vpath->vdev; 998221167Sgnn 999221167Sgnn struct lro_entry *queued = NULL; 1000221167Sgnn struct lro_ctrl *lro = &vpath->lro; 1001221167Sgnn 1002221167Sgnn /* get the interface pointer */ 1003221167Sgnn ifnet_t ifp = vdev->ifp; 1004221167Sgnn 1005221167Sgnn do { 1006221167Sgnn if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { 1007221167Sgnn vxge_hal_ring_rxd_post(vpath_handle, rxdh); 1008221167Sgnn status = VXGE_HAL_FAIL; 1009221167Sgnn break; 1010221167Sgnn } 1011221167Sgnn 1012221167Sgnn VXGE_DRV_STATS(vpath, rx_compl); 1013221167Sgnn rxd_priv = (vxge_rxd_priv_t *) dtr_priv; 1014221167Sgnn 1015221167Sgnn /* Gets details of mbuf i.e., packet length */ 1016221167Sgnn vxge_rx_rxd_1b_get(vpath, rxdh, dtr_priv); 1017221167Sgnn 1018221167Sgnn /* 1019221167Sgnn * Prepare one buffer to send it to upper layer Since upper 1020221167Sgnn * layer frees the buffer do not use rxd_priv->mbuf_pkt. 1021221167Sgnn * Meanwhile prepare a new buffer, do mapping, use with the 1022221167Sgnn * current descriptor and post descriptor back to ring vpath 1023221167Sgnn */ 1024221167Sgnn mbuf_up = rxd_priv->mbuf_pkt; 1025221167Sgnn if (t_code != VXGE_HAL_RING_RXD_T_CODE_OK) { 1026221167Sgnn 1027221167Sgnn ifp->if_ierrors++; 1028221167Sgnn VXGE_DRV_STATS(vpath, rx_tcode); 1029221167Sgnn status = vxge_hal_ring_handle_tcode(vpath_handle, 1030221167Sgnn rxdh, t_code); 1031221167Sgnn 1032221167Sgnn /* 1033221167Sgnn * If transfer code is not for unknown protocols and 1034221167Sgnn * vxge_hal_device_handle_tcode is NOT returned 1035221167Sgnn * VXGE_HAL_OK 1036221167Sgnn * drop this packet and increment rx_tcode stats 1037221167Sgnn */ 1038221167Sgnn if ((status != VXGE_HAL_OK) && 1039221167Sgnn (t_code != VXGE_HAL_RING_T_CODE_L3_PKT_ERR)) { 1040221167Sgnn 1041221167Sgnn vxge_free_packet(mbuf_up); 1042221167Sgnn vxge_hal_ring_rxd_post(vpath_handle, rxdh); 1043221167Sgnn continue; 1044221167Sgnn } 1045221167Sgnn } 1046221167Sgnn 1047221167Sgnn if (vxge_rx_rxd_1b_set(vpath, rxdh, dtr_priv)) { 1048221167Sgnn /* 1049221167Sgnn * If unable to allocate buffer, post descriptor back 1050221167Sgnn * to vpath for future processing of same packet. 1051221167Sgnn */ 1052221167Sgnn vxge_hal_ring_rxd_post(vpath_handle, rxdh); 1053221167Sgnn continue; 1054221167Sgnn } 1055221167Sgnn 1056221167Sgnn /* Get the extended information */ 1057221167Sgnn vxge_hal_ring_rxd_1b_info_get(vpath_handle, rxdh, &ext_info); 1058221167Sgnn 1059221167Sgnn /* post descriptor with newly allocated mbuf back to vpath */ 1060221167Sgnn vxge_hal_ring_rxd_post(vpath_handle, rxdh); 1061221167Sgnn vpath->rxd_posted++; 1062221167Sgnn 1063221167Sgnn if (vpath->rxd_posted % VXGE_RXD_REPLENISH_COUNT == 0) 1064221167Sgnn vxge_hal_ring_rxd_post_post_db(vpath_handle); 1065221167Sgnn 1066221167Sgnn /* 1067221167Sgnn * Set successfully computed checksums in the mbuf. 1068221167Sgnn * Leave the rest to the stack to be reverified. 1069221167Sgnn */ 1070221167Sgnn vxge_rx_checksum(ext_info, mbuf_up); 1071221167Sgnn 1072221167Sgnn#if __FreeBSD_version >= 800000 1073281955Shiren M_HASHTYPE_SET(mbuf_up, M_HASHTYPE_OPAQUE); 1074221167Sgnn mbuf_up->m_pkthdr.flowid = vpath->vp_index; 1075221167Sgnn#endif 1076221167Sgnn /* Post-Read sync for buffers */ 1077221167Sgnn bus_dmamap_sync(vpath->dma_tag_rx, rxd_priv->dma_map, 1078221167Sgnn BUS_DMASYNC_POSTREAD); 1079221167Sgnn 1080221167Sgnn vxge_rx_input(ifp, mbuf_up, vpath); 1081221167Sgnn 1082221167Sgnn } while (vxge_hal_ring_rxd_next_completed(vpath_handle, &rxdh, 1083221167Sgnn &dtr_priv, &t_code) == VXGE_HAL_OK); 1084221167Sgnn 1085221167Sgnn /* Flush any outstanding LRO work */ 1086221167Sgnn if (vpath->lro_enable && vpath->lro.lro_cnt) { 1087221167Sgnn while ((queued = SLIST_FIRST(&lro->lro_active)) != NULL) { 1088221167Sgnn SLIST_REMOVE_HEAD(&lro->lro_active, next); 1089221167Sgnn tcp_lro_flush(lro, queued); 1090221167Sgnn } 1091221167Sgnn } 1092221167Sgnn 1093221167Sgnn return (status); 1094221167Sgnn} 1095221167Sgnn 1096221167Sgnnstatic inline void 1097221167Sgnnvxge_rx_input(ifnet_t ifp, mbuf_t mbuf_up, vxge_vpath_t *vpath) 1098221167Sgnn{ 1099221167Sgnn if (vpath->lro_enable && vpath->lro.lro_cnt) { 1100221167Sgnn if (tcp_lro_rx(&vpath->lro, mbuf_up, 0) == 0) 1101221167Sgnn return; 1102221167Sgnn } 1103221167Sgnn (*ifp->if_input) (ifp, mbuf_up); 1104221167Sgnn} 1105221167Sgnn 1106221167Sgnnstatic inline void 1107221167Sgnnvxge_rx_checksum(vxge_hal_ring_rxd_info_t ext_info, mbuf_t mbuf_up) 1108221167Sgnn{ 1109221167Sgnn 1110221167Sgnn if (!(ext_info.proto & VXGE_HAL_FRAME_PROTO_IP_FRAG) && 1111221167Sgnn (ext_info.proto & VXGE_HAL_FRAME_PROTO_TCP_OR_UDP) && 1112221167Sgnn ext_info.l3_cksum_valid && ext_info.l4_cksum_valid) { 1113221167Sgnn 1114221167Sgnn mbuf_up->m_pkthdr.csum_data = htons(0xffff); 1115221167Sgnn 1116221167Sgnn mbuf_up->m_pkthdr.csum_flags = CSUM_IP_CHECKED; 1117221167Sgnn mbuf_up->m_pkthdr.csum_flags |= CSUM_IP_VALID; 1118221167Sgnn mbuf_up->m_pkthdr.csum_flags |= 1119221167Sgnn (CSUM_DATA_VALID | CSUM_PSEUDO_HDR); 1120221167Sgnn 1121221167Sgnn } else { 1122221167Sgnn 1123221167Sgnn if (ext_info.vlan) { 1124221167Sgnn mbuf_up->m_pkthdr.ether_vtag = ext_info.vlan; 1125221167Sgnn mbuf_up->m_flags |= M_VLANTAG; 1126221167Sgnn } 1127221167Sgnn } 1128221167Sgnn} 1129221167Sgnn 1130221167Sgnn/* 1131221167Sgnn * vxge_rx_term During unload terminate and free all descriptors 1132221167Sgnn * @vpath_handle Rx vpath Handle @rxdh Rx Descriptor Handle @state Descriptor 1133221167Sgnn * State @userdata Per-adapter Data @reopen vpath open/reopen option 1134221167Sgnn */ 1135221167Sgnn/* ARGSUSED */ 1136221167Sgnnvoid 1137221167Sgnnvxge_rx_term(vxge_hal_vpath_h vpath_handle, vxge_hal_rxd_h rxdh, 1138221167Sgnn void *dtr_priv, vxge_hal_rxd_state_e state, void *userdata, 1139221167Sgnn vxge_hal_reopen_e reopen) 1140221167Sgnn{ 1141221167Sgnn vxge_vpath_t *vpath = (vxge_vpath_t *) userdata; 1142221167Sgnn vxge_rxd_priv_t *rxd_priv = (vxge_rxd_priv_t *) dtr_priv; 1143221167Sgnn 1144221167Sgnn if (state != VXGE_HAL_RXD_STATE_POSTED) 1145221167Sgnn return; 1146221167Sgnn 1147221167Sgnn if (rxd_priv != NULL) { 1148221167Sgnn bus_dmamap_sync(vpath->dma_tag_rx, rxd_priv->dma_map, 1149221167Sgnn BUS_DMASYNC_POSTREAD); 1150221167Sgnn bus_dmamap_unload(vpath->dma_tag_rx, rxd_priv->dma_map); 1151221167Sgnn bus_dmamap_destroy(vpath->dma_tag_rx, rxd_priv->dma_map); 1152221167Sgnn 1153221167Sgnn vxge_free_packet(rxd_priv->mbuf_pkt); 1154221167Sgnn } 1155221167Sgnn /* Free the descriptor */ 1156221167Sgnn vxge_hal_ring_rxd_free(vpath_handle, rxdh); 1157221167Sgnn} 1158221167Sgnn 1159221167Sgnn/* 1160221167Sgnn * vxge_rx_rxd_1b_get 1161221167Sgnn * Get descriptors of packet to send up 1162221167Sgnn */ 1163221167Sgnnvoid 1164221167Sgnnvxge_rx_rxd_1b_get(vxge_vpath_t *vpath, vxge_hal_rxd_h rxdh, void *dtr_priv) 1165221167Sgnn{ 1166221167Sgnn vxge_rxd_priv_t *rxd_priv = (vxge_rxd_priv_t *) dtr_priv; 1167221167Sgnn mbuf_t mbuf_up = rxd_priv->mbuf_pkt; 1168221167Sgnn 1169221167Sgnn /* Retrieve data from completed descriptor */ 1170221167Sgnn vxge_hal_ring_rxd_1b_get(vpath->handle, rxdh, &rxd_priv->dma_addr[0], 1171221167Sgnn (u32 *) &rxd_priv->dma_sizes[0]); 1172221167Sgnn 1173221167Sgnn /* Update newly created buffer to be sent up with packet length */ 1174221167Sgnn mbuf_up->m_len = rxd_priv->dma_sizes[0]; 1175221167Sgnn mbuf_up->m_pkthdr.len = rxd_priv->dma_sizes[0]; 1176221167Sgnn mbuf_up->m_next = NULL; 1177221167Sgnn} 1178221167Sgnn 1179221167Sgnn/* 1180221167Sgnn * vxge_rx_rxd_1b_set 1181221167Sgnn * Allocates new mbufs to be placed into descriptors 1182221167Sgnn */ 1183221167Sgnnint 1184221167Sgnnvxge_rx_rxd_1b_set(vxge_vpath_t *vpath, vxge_hal_rxd_h rxdh, void *dtr_priv) 1185221167Sgnn{ 1186221167Sgnn int num_segs, err = 0; 1187221167Sgnn 1188221167Sgnn mbuf_t mbuf_pkt; 1189221167Sgnn bus_dmamap_t dma_map; 1190221167Sgnn bus_dma_segment_t dma_buffers[1]; 1191221167Sgnn vxge_rxd_priv_t *rxd_priv = (vxge_rxd_priv_t *) dtr_priv; 1192221167Sgnn 1193221167Sgnn vxge_dev_t *vdev = vpath->vdev; 1194221167Sgnn 1195243857Sglebius mbuf_pkt = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, vdev->rx_mbuf_sz); 1196221167Sgnn if (!mbuf_pkt) { 1197221167Sgnn err = ENOBUFS; 1198221167Sgnn VXGE_DRV_STATS(vpath, rx_no_buf); 1199221167Sgnn device_printf(vdev->ndev, "out of memory to allocate mbuf\n"); 1200221167Sgnn goto _exit0; 1201221167Sgnn } 1202221167Sgnn 1203221167Sgnn /* Update mbuf's length, packet length and receive interface */ 1204221167Sgnn mbuf_pkt->m_len = vdev->rx_mbuf_sz; 1205221167Sgnn mbuf_pkt->m_pkthdr.len = vdev->rx_mbuf_sz; 1206221167Sgnn mbuf_pkt->m_pkthdr.rcvif = vdev->ifp; 1207221167Sgnn 1208221167Sgnn /* Load DMA map */ 1209221167Sgnn err = vxge_dma_mbuf_coalesce(vpath->dma_tag_rx, vpath->extra_dma_map, 1210221167Sgnn &mbuf_pkt, dma_buffers, &num_segs); 1211221167Sgnn if (err != 0) { 1212221167Sgnn VXGE_DRV_STATS(vpath, rx_map_fail); 1213221167Sgnn vxge_free_packet(mbuf_pkt); 1214221167Sgnn goto _exit0; 1215221167Sgnn } 1216221167Sgnn 1217221167Sgnn /* Unload DMA map of mbuf in current descriptor */ 1218221167Sgnn bus_dmamap_sync(vpath->dma_tag_rx, rxd_priv->dma_map, 1219221167Sgnn BUS_DMASYNC_POSTREAD); 1220221167Sgnn bus_dmamap_unload(vpath->dma_tag_rx, rxd_priv->dma_map); 1221221167Sgnn 1222221167Sgnn /* Update descriptor private data */ 1223221167Sgnn dma_map = rxd_priv->dma_map; 1224221167Sgnn rxd_priv->mbuf_pkt = mbuf_pkt; 1225221167Sgnn rxd_priv->dma_addr[0] = htole64(dma_buffers->ds_addr); 1226221167Sgnn rxd_priv->dma_map = vpath->extra_dma_map; 1227221167Sgnn vpath->extra_dma_map = dma_map; 1228221167Sgnn 1229221167Sgnn /* Pre-Read/Write sync */ 1230221167Sgnn bus_dmamap_sync(vpath->dma_tag_rx, rxd_priv->dma_map, 1231221167Sgnn BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 1232221167Sgnn 1233221167Sgnn /* Set descriptor buffer */ 1234221167Sgnn vxge_hal_ring_rxd_1b_set(rxdh, rxd_priv->dma_addr[0], vdev->rx_mbuf_sz); 1235221167Sgnn 1236221167Sgnn_exit0: 1237221167Sgnn return (err); 1238221167Sgnn} 1239221167Sgnn 1240221167Sgnn/* 1241221167Sgnn * vxge_link_up 1242221167Sgnn * Callback for Link-up indication from HAL 1243221167Sgnn */ 1244221167Sgnn/* ARGSUSED */ 1245221167Sgnnvoid 1246221167Sgnnvxge_link_up(vxge_hal_device_h devh, void *userdata) 1247221167Sgnn{ 1248221167Sgnn int i; 1249221167Sgnn vxge_vpath_t *vpath; 1250221167Sgnn vxge_hal_device_hw_info_t *hw_info; 1251221167Sgnn 1252221167Sgnn vxge_dev_t *vdev = (vxge_dev_t *) userdata; 1253221167Sgnn hw_info = &vdev->config.hw_info; 1254221167Sgnn 1255221167Sgnn ifnet_t ifp = vdev->ifp; 1256221167Sgnn 1257221167Sgnn if (vdev->config.intr_mode == VXGE_HAL_INTR_MODE_MSIX) { 1258221167Sgnn for (i = 0; i < vdev->no_of_vpath; i++) { 1259221167Sgnn vpath = &(vdev->vpaths[i]); 1260221167Sgnn vxge_hal_vpath_tti_ci_set(vpath->handle); 1261221167Sgnn vxge_hal_vpath_rti_ci_set(vpath->handle); 1262221167Sgnn } 1263221167Sgnn } 1264221167Sgnn 1265221167Sgnn if (vdev->is_privilaged && (hw_info->ports > 1)) { 1266221167Sgnn vxge_active_port_update(vdev); 1267221167Sgnn device_printf(vdev->ndev, 1268221167Sgnn "Active Port : %lld\n", vdev->active_port); 1269221167Sgnn } 1270221167Sgnn 1271221167Sgnn ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 1272221167Sgnn if_link_state_change(ifp, LINK_STATE_UP); 1273221167Sgnn} 1274221167Sgnn 1275221167Sgnn/* 1276221167Sgnn * vxge_link_down 1277221167Sgnn * Callback for Link-down indication from HAL 1278221167Sgnn */ 1279221167Sgnn/* ARGSUSED */ 1280221167Sgnnvoid 1281221167Sgnnvxge_link_down(vxge_hal_device_h devh, void *userdata) 1282221167Sgnn{ 1283221167Sgnn int i; 1284221167Sgnn vxge_vpath_t *vpath; 1285221167Sgnn vxge_dev_t *vdev = (vxge_dev_t *) userdata; 1286221167Sgnn 1287221167Sgnn ifnet_t ifp = vdev->ifp; 1288221167Sgnn 1289221167Sgnn if (vdev->config.intr_mode == VXGE_HAL_INTR_MODE_MSIX) { 1290221167Sgnn for (i = 0; i < vdev->no_of_vpath; i++) { 1291221167Sgnn vpath = &(vdev->vpaths[i]); 1292221167Sgnn vxge_hal_vpath_tti_ci_reset(vpath->handle); 1293221167Sgnn vxge_hal_vpath_rti_ci_reset(vpath->handle); 1294221167Sgnn } 1295221167Sgnn } 1296221167Sgnn 1297221167Sgnn ifp->if_drv_flags |= IFF_DRV_OACTIVE; 1298221167Sgnn if_link_state_change(ifp, LINK_STATE_DOWN); 1299221167Sgnn} 1300221167Sgnn 1301221167Sgnn/* 1302221167Sgnn * vxge_reset 1303221167Sgnn */ 1304221167Sgnnvoid 1305221167Sgnnvxge_reset(vxge_dev_t *vdev) 1306221167Sgnn{ 1307221167Sgnn if (!vdev->is_initialized) 1308221167Sgnn return; 1309221167Sgnn 1310221167Sgnn VXGE_DRV_LOCK(vdev); 1311221167Sgnn vxge_stop_locked(vdev); 1312221167Sgnn vxge_init_locked(vdev); 1313221167Sgnn VXGE_DRV_UNLOCK(vdev); 1314221167Sgnn} 1315221167Sgnn 1316221167Sgnn/* 1317221167Sgnn * vxge_crit_error 1318221167Sgnn * Callback for Critical error indication from HAL 1319221167Sgnn */ 1320221167Sgnn/* ARGSUSED */ 1321221167Sgnnvoid 1322221167Sgnnvxge_crit_error(vxge_hal_device_h devh, void *userdata, 1323221167Sgnn vxge_hal_event_e type, u64 serr_data) 1324221167Sgnn{ 1325221167Sgnn vxge_dev_t *vdev = (vxge_dev_t *) userdata; 1326221167Sgnn ifnet_t ifp = vdev->ifp; 1327221167Sgnn 1328221167Sgnn switch (type) { 1329221167Sgnn case VXGE_HAL_EVENT_SERR: 1330221167Sgnn case VXGE_HAL_EVENT_KDFCCTL: 1331221167Sgnn case VXGE_HAL_EVENT_CRITICAL: 1332221167Sgnn vxge_hal_device_intr_disable(vdev->devh); 1333221167Sgnn ifp->if_drv_flags |= IFF_DRV_OACTIVE; 1334221167Sgnn if_link_state_change(ifp, LINK_STATE_DOWN); 1335221167Sgnn break; 1336221167Sgnn default: 1337221167Sgnn break; 1338221167Sgnn } 1339221167Sgnn} 1340221167Sgnn 1341221167Sgnn/* 1342221167Sgnn * vxge_ifp_setup 1343221167Sgnn */ 1344221167Sgnnint 1345221167Sgnnvxge_ifp_setup(device_t ndev) 1346221167Sgnn{ 1347221167Sgnn ifnet_t ifp; 1348221167Sgnn int i, j, err = 0; 1349221167Sgnn 1350221167Sgnn vxge_dev_t *vdev = (vxge_dev_t *) device_get_softc(ndev); 1351221167Sgnn 1352221167Sgnn for (i = 0, j = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) { 1353221167Sgnn if (!bVAL1(vdev->config.hw_info.vpath_mask, i)) 1354221167Sgnn continue; 1355221167Sgnn 1356221167Sgnn if (j >= vdev->no_of_vpath) 1357221167Sgnn break; 1358221167Sgnn 1359221167Sgnn vdev->vpaths[j].vp_id = i; 1360221167Sgnn vdev->vpaths[j].vp_index = j; 1361221167Sgnn vdev->vpaths[j].vdev = vdev; 1362221167Sgnn vdev->vpaths[j].is_configured = TRUE; 1363221167Sgnn 1364221167Sgnn vxge_os_memcpy((u8 *) vdev->vpaths[j].mac_addr, 1365221167Sgnn (u8 *) (vdev->config.hw_info.mac_addrs[i]), 1366221167Sgnn (size_t) ETHER_ADDR_LEN); 1367221167Sgnn j++; 1368221167Sgnn } 1369221167Sgnn 1370221167Sgnn /* Get interface ifnet structure for this Ether device */ 1371221167Sgnn ifp = if_alloc(IFT_ETHER); 1372221167Sgnn if (ifp == NULL) { 1373221167Sgnn device_printf(vdev->ndev, 1374221167Sgnn "memory allocation for ifnet failed\n"); 1375221167Sgnn err = ENXIO; 1376221167Sgnn goto _exit0; 1377221167Sgnn } 1378221167Sgnn vdev->ifp = ifp; 1379221167Sgnn 1380221167Sgnn /* Initialize interface ifnet structure */ 1381221167Sgnn if_initname(ifp, device_get_name(ndev), device_get_unit(ndev)); 1382221167Sgnn 1383221167Sgnn ifp->if_baudrate = VXGE_BAUDRATE; 1384221167Sgnn ifp->if_init = vxge_init; 1385221167Sgnn ifp->if_softc = vdev; 1386221167Sgnn ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 1387221167Sgnn ifp->if_ioctl = vxge_ioctl; 1388221167Sgnn ifp->if_start = vxge_send; 1389221167Sgnn 1390221167Sgnn#if __FreeBSD_version >= 800000 1391221167Sgnn ifp->if_transmit = vxge_mq_send; 1392221167Sgnn ifp->if_qflush = vxge_mq_qflush; 1393221167Sgnn#endif 1394221167Sgnn ifp->if_snd.ifq_drv_maxlen = max(vdev->config.ifq_maxlen, ifqmaxlen); 1395221167Sgnn IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen); 1396221167Sgnn /* IFQ_SET_READY(&ifp->if_snd); */ 1397221167Sgnn 1398221167Sgnn ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header); 1399221167Sgnn 1400221167Sgnn ifp->if_capabilities |= IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM; 1401221167Sgnn ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU; 1402221167Sgnn ifp->if_capabilities |= IFCAP_JUMBO_MTU; 1403221167Sgnn 1404221167Sgnn if (vdev->config.tso_enable) 1405221167Sgnn vxge_tso_config(vdev); 1406221167Sgnn 1407221167Sgnn if (vdev->config.lro_enable) 1408221167Sgnn ifp->if_capabilities |= IFCAP_LRO; 1409221167Sgnn 1410221167Sgnn ifp->if_capenable = ifp->if_capabilities; 1411221167Sgnn 1412221167Sgnn strlcpy(vdev->ndev_name, device_get_nameunit(ndev), 1413221167Sgnn sizeof(vdev->ndev_name)); 1414221167Sgnn 1415221167Sgnn /* Attach the interface */ 1416221167Sgnn ether_ifattach(ifp, vdev->vpaths[0].mac_addr); 1417221167Sgnn 1418221167Sgnn_exit0: 1419221167Sgnn return (err); 1420221167Sgnn} 1421221167Sgnn 1422221167Sgnn/* 1423221167Sgnn * vxge_isr_setup 1424221167Sgnn * Register isr functions 1425221167Sgnn */ 1426221167Sgnnint 1427221167Sgnnvxge_isr_setup(vxge_dev_t *vdev) 1428221167Sgnn{ 1429221167Sgnn int i, irq_rid, err = 0; 1430221167Sgnn vxge_vpath_t *vpath; 1431221167Sgnn 1432221167Sgnn void *isr_func_arg; 1433221167Sgnn void (*isr_func_ptr) (void *); 1434221167Sgnn 1435221167Sgnn switch (vdev->config.intr_mode) { 1436221167Sgnn case VXGE_HAL_INTR_MODE_IRQLINE: 1437221167Sgnn err = bus_setup_intr(vdev->ndev, 1438221167Sgnn vdev->config.isr_info[0].irq_res, 1439221167Sgnn (INTR_TYPE_NET | INTR_MPSAFE), 1440221167Sgnn vxge_isr_filter, vxge_isr_line, vdev, 1441221167Sgnn &vdev->config.isr_info[0].irq_handle); 1442221167Sgnn break; 1443221167Sgnn 1444221167Sgnn case VXGE_HAL_INTR_MODE_MSIX: 1445221167Sgnn for (i = 0; i < vdev->intr_count; i++) { 1446221167Sgnn 1447221167Sgnn irq_rid = vdev->config.isr_info[i].irq_rid; 1448221167Sgnn vpath = &vdev->vpaths[irq_rid / 4]; 1449221167Sgnn 1450221167Sgnn if ((irq_rid % 4) == 2) { 1451221167Sgnn isr_func_ptr = vxge_isr_msix; 1452221167Sgnn isr_func_arg = (void *) vpath; 1453221167Sgnn } else if ((irq_rid % 4) == 3) { 1454221167Sgnn isr_func_ptr = vxge_isr_msix_alarm; 1455221167Sgnn isr_func_arg = (void *) vpath; 1456221167Sgnn } else 1457221167Sgnn break; 1458221167Sgnn 1459221167Sgnn err = bus_setup_intr(vdev->ndev, 1460221167Sgnn vdev->config.isr_info[i].irq_res, 1461221167Sgnn (INTR_TYPE_NET | INTR_MPSAFE), NULL, 1462221167Sgnn (void *) isr_func_ptr, (void *) isr_func_arg, 1463221167Sgnn &vdev->config.isr_info[i].irq_handle); 1464221167Sgnn if (err != 0) 1465221167Sgnn break; 1466221167Sgnn } 1467221167Sgnn 1468221167Sgnn if (err != 0) { 1469221167Sgnn /* Teardown interrupt handler */ 1470221167Sgnn while (--i > 0) 1471221167Sgnn bus_teardown_intr(vdev->ndev, 1472221167Sgnn vdev->config.isr_info[i].irq_res, 1473221167Sgnn vdev->config.isr_info[i].irq_handle); 1474221167Sgnn } 1475221167Sgnn break; 1476221167Sgnn } 1477221167Sgnn 1478221167Sgnn return (err); 1479221167Sgnn} 1480221167Sgnn 1481221167Sgnn/* 1482221167Sgnn * vxge_isr_filter 1483221167Sgnn * ISR filter function - filter interrupts from other shared devices 1484221167Sgnn */ 1485221167Sgnnint 1486221167Sgnnvxge_isr_filter(void *handle) 1487221167Sgnn{ 1488221167Sgnn u64 val64 = 0; 1489221167Sgnn vxge_dev_t *vdev = (vxge_dev_t *) handle; 1490221167Sgnn __hal_device_t *hldev = (__hal_device_t *) vdev->devh; 1491221167Sgnn 1492221167Sgnn vxge_hal_common_reg_t *common_reg = 1493221167Sgnn (vxge_hal_common_reg_t *) (hldev->common_reg); 1494221167Sgnn 1495221167Sgnn val64 = vxge_os_pio_mem_read64(vdev->pdev, (vdev->devh)->regh0, 1496221167Sgnn &common_reg->titan_general_int_status); 1497221167Sgnn 1498221167Sgnn return ((val64) ? FILTER_SCHEDULE_THREAD : FILTER_STRAY); 1499221167Sgnn} 1500221167Sgnn 1501221167Sgnn/* 1502221167Sgnn * vxge_isr_line 1503221167Sgnn * Interrupt service routine for Line interrupts 1504221167Sgnn */ 1505221167Sgnnvoid 1506221167Sgnnvxge_isr_line(void *vdev_ptr) 1507221167Sgnn{ 1508221167Sgnn vxge_dev_t *vdev = (vxge_dev_t *) vdev_ptr; 1509221167Sgnn 1510221167Sgnn vxge_hal_device_handle_irq(vdev->devh, 0); 1511221167Sgnn} 1512221167Sgnn 1513221167Sgnnvoid 1514221167Sgnnvxge_isr_msix(void *vpath_ptr) 1515221167Sgnn{ 1516221167Sgnn u32 got_rx = 0; 1517221167Sgnn u32 got_tx = 0; 1518221167Sgnn 1519221167Sgnn __hal_virtualpath_t *hal_vpath; 1520221167Sgnn vxge_vpath_t *vpath = (vxge_vpath_t *) vpath_ptr; 1521221167Sgnn vxge_dev_t *vdev = vpath->vdev; 1522221167Sgnn hal_vpath = ((__hal_vpath_handle_t *) vpath->handle)->vpath; 1523221167Sgnn 1524221167Sgnn VXGE_DRV_STATS(vpath, isr_msix); 1525221167Sgnn VXGE_HAL_DEVICE_STATS_SW_INFO_TRAFFIC_INTR(vdev->devh); 1526221167Sgnn 1527221167Sgnn vxge_hal_vpath_mf_msix_mask(vpath->handle, vpath->msix_vec); 1528221167Sgnn 1529221167Sgnn /* processing rx */ 1530221167Sgnn vxge_hal_vpath_poll_rx(vpath->handle, &got_rx); 1531221167Sgnn 1532221167Sgnn /* processing tx */ 1533221167Sgnn if (hal_vpath->vp_config->fifo.enable) { 1534221167Sgnn vxge_intr_coalesce_tx(vpath); 1535221167Sgnn vxge_hal_vpath_poll_tx(vpath->handle, &got_tx); 1536221167Sgnn } 1537221167Sgnn 1538221167Sgnn vxge_hal_vpath_mf_msix_unmask(vpath->handle, vpath->msix_vec); 1539221167Sgnn} 1540221167Sgnn 1541221167Sgnnvoid 1542221167Sgnnvxge_isr_msix_alarm(void *vpath_ptr) 1543221167Sgnn{ 1544221167Sgnn int i; 1545221167Sgnn vxge_hal_status_e status = VXGE_HAL_OK; 1546221167Sgnn 1547221167Sgnn vxge_vpath_t *vpath = (vxge_vpath_t *) vpath_ptr; 1548221167Sgnn vxge_dev_t *vdev = vpath->vdev; 1549221167Sgnn 1550221167Sgnn VXGE_HAL_DEVICE_STATS_SW_INFO_NOT_TRAFFIC_INTR(vdev->devh); 1551221167Sgnn 1552221167Sgnn /* Process alarms in each vpath */ 1553221167Sgnn for (i = 0; i < vdev->no_of_vpath; i++) { 1554221167Sgnn 1555221167Sgnn vpath = &(vdev->vpaths[i]); 1556221167Sgnn vxge_hal_vpath_mf_msix_mask(vpath->handle, 1557221167Sgnn vpath->msix_vec_alarm); 1558221167Sgnn status = vxge_hal_vpath_alarm_process(vpath->handle, 0); 1559221167Sgnn if ((status == VXGE_HAL_ERR_EVENT_SLOT_FREEZE) || 1560221167Sgnn (status == VXGE_HAL_ERR_EVENT_SERR)) { 1561221167Sgnn device_printf(vdev->ndev, 1562221167Sgnn "processing alarms urecoverable error %x\n", 1563221167Sgnn status); 1564221167Sgnn 1565221167Sgnn /* Stop the driver */ 1566221167Sgnn vdev->is_initialized = FALSE; 1567221167Sgnn break; 1568221167Sgnn } 1569221167Sgnn vxge_hal_vpath_mf_msix_unmask(vpath->handle, 1570221167Sgnn vpath->msix_vec_alarm); 1571221167Sgnn } 1572221167Sgnn} 1573221167Sgnn 1574221167Sgnn/* 1575221167Sgnn * vxge_msix_enable 1576221167Sgnn */ 1577221167Sgnnvxge_hal_status_e 1578221167Sgnnvxge_msix_enable(vxge_dev_t *vdev) 1579221167Sgnn{ 1580221167Sgnn int i, first_vp_id, msix_id; 1581221167Sgnn 1582221167Sgnn vxge_vpath_t *vpath; 1583221167Sgnn vxge_hal_status_e status = VXGE_HAL_OK; 1584221167Sgnn 1585221167Sgnn /* 1586221167Sgnn * Unmasking and Setting MSIX vectors before enabling interrupts 1587221167Sgnn * tim[] : 0 - Tx ## 1 - Rx ## 2 - UMQ-DMQ ## 0 - BITMAP 1588221167Sgnn */ 1589221167Sgnn int tim[4] = {0, 1, 0, 0}; 1590221167Sgnn 1591221167Sgnn for (i = 0; i < vdev->no_of_vpath; i++) { 1592221167Sgnn 1593221167Sgnn vpath = vdev->vpaths + i; 1594221167Sgnn first_vp_id = vdev->vpaths[0].vp_id; 1595221167Sgnn 1596221167Sgnn msix_id = vpath->vp_id * VXGE_HAL_VPATH_MSIX_ACTIVE; 1597221167Sgnn tim[1] = vpath->msix_vec = msix_id + 1; 1598221167Sgnn 1599221167Sgnn vpath->msix_vec_alarm = first_vp_id * 1600221167Sgnn VXGE_HAL_VPATH_MSIX_ACTIVE + VXGE_HAL_VPATH_MSIX_ALARM_ID; 1601221167Sgnn 1602221167Sgnn status = vxge_hal_vpath_mf_msix_set(vpath->handle, 1603221167Sgnn tim, VXGE_HAL_VPATH_MSIX_ALARM_ID); 1604221167Sgnn 1605221167Sgnn if (status != VXGE_HAL_OK) { 1606221167Sgnn device_printf(vdev->ndev, 1607221167Sgnn "failed to set msix vectors to vpath\n"); 1608221167Sgnn break; 1609221167Sgnn } 1610221167Sgnn 1611221167Sgnn vxge_hal_vpath_mf_msix_unmask(vpath->handle, vpath->msix_vec); 1612221167Sgnn vxge_hal_vpath_mf_msix_unmask(vpath->handle, 1613221167Sgnn vpath->msix_vec_alarm); 1614221167Sgnn } 1615221167Sgnn 1616221167Sgnn return (status); 1617221167Sgnn} 1618221167Sgnn 1619221167Sgnn/* 1620221167Sgnn * vxge_media_init 1621221167Sgnn * Initializes, adds and sets media 1622221167Sgnn */ 1623221167Sgnnvoid 1624221167Sgnnvxge_media_init(vxge_dev_t *vdev) 1625221167Sgnn{ 1626221167Sgnn ifmedia_init(&vdev->media, 1627221167Sgnn IFM_IMASK, vxge_media_change, vxge_media_status); 1628221167Sgnn 1629221167Sgnn /* Add supported media */ 1630221167Sgnn ifmedia_add(&vdev->media, 1631221167Sgnn IFM_ETHER | vdev->ifm_optics | IFM_FDX, 1632221167Sgnn 0, NULL); 1633221167Sgnn 1634221167Sgnn /* Set media */ 1635221167Sgnn ifmedia_add(&vdev->media, IFM_ETHER | IFM_AUTO, 0, NULL); 1636221167Sgnn ifmedia_set(&vdev->media, IFM_ETHER | IFM_AUTO); 1637221167Sgnn} 1638221167Sgnn 1639221167Sgnn/* 1640221167Sgnn * vxge_media_status 1641221167Sgnn * Callback for interface media settings 1642221167Sgnn */ 1643221167Sgnnvoid 1644221167Sgnnvxge_media_status(ifnet_t ifp, struct ifmediareq *ifmr) 1645221167Sgnn{ 1646221167Sgnn vxge_dev_t *vdev = (vxge_dev_t *) ifp->if_softc; 1647221167Sgnn vxge_hal_device_t *hldev = vdev->devh; 1648221167Sgnn 1649221167Sgnn ifmr->ifm_status = IFM_AVALID; 1650221167Sgnn ifmr->ifm_active = IFM_ETHER; 1651221167Sgnn 1652221167Sgnn /* set link state */ 1653221167Sgnn if (vxge_hal_device_link_state_get(hldev) == VXGE_HAL_LINK_UP) { 1654221167Sgnn ifmr->ifm_status |= IFM_ACTIVE; 1655221167Sgnn ifmr->ifm_active |= vdev->ifm_optics | IFM_FDX; 1656221167Sgnn if_link_state_change(ifp, LINK_STATE_UP); 1657221167Sgnn } 1658221167Sgnn} 1659221167Sgnn 1660221167Sgnn/* 1661221167Sgnn * vxge_media_change 1662221167Sgnn * Media change driver callback 1663221167Sgnn */ 1664221167Sgnnint 1665221167Sgnnvxge_media_change(ifnet_t ifp) 1666221167Sgnn{ 1667221167Sgnn vxge_dev_t *vdev = (vxge_dev_t *) ifp->if_softc; 1668221167Sgnn struct ifmedia *ifmediap = &vdev->media; 1669221167Sgnn 1670221167Sgnn return (IFM_TYPE(ifmediap->ifm_media) != IFM_ETHER ? EINVAL : 0); 1671221167Sgnn} 1672221167Sgnn 1673221167Sgnn/* 1674221167Sgnn * Allocate PCI resources 1675221167Sgnn */ 1676221167Sgnnint 1677221167Sgnnvxge_alloc_resources(vxge_dev_t *vdev) 1678221167Sgnn{ 1679221167Sgnn int err = 0; 1680221167Sgnn vxge_pci_info_t *pci_info = NULL; 1681221167Sgnn vxge_free_resources_e error_level = VXGE_FREE_NONE; 1682221167Sgnn 1683221167Sgnn device_t ndev = vdev->ndev; 1684221167Sgnn 1685221167Sgnn /* Allocate Buffer for HAL Device Configuration */ 1686221167Sgnn vdev->device_config = (vxge_hal_device_config_t *) 1687221167Sgnn vxge_mem_alloc(sizeof(vxge_hal_device_config_t)); 1688221167Sgnn 1689221167Sgnn if (!vdev->device_config) { 1690221167Sgnn err = ENOMEM; 1691221167Sgnn error_level = VXGE_DISABLE_PCI_BUSMASTER; 1692221167Sgnn device_printf(vdev->ndev, 1693221167Sgnn "failed to allocate memory for device config\n"); 1694221167Sgnn goto _exit0; 1695221167Sgnn } 1696221167Sgnn 1697221167Sgnn 1698221167Sgnn pci_info = (vxge_pci_info_t *) vxge_mem_alloc(sizeof(vxge_pci_info_t)); 1699221167Sgnn if (!pci_info) { 1700221167Sgnn error_level = VXGE_FREE_DEVICE_CONFIG; 1701221167Sgnn err = ENOMEM; 1702221167Sgnn device_printf(vdev->ndev, 1703221167Sgnn "failed to allocate memory for pci info\n"); 1704221167Sgnn goto _exit0; 1705221167Sgnn } 1706221167Sgnn pci_info->ndev = ndev; 1707221167Sgnn vdev->pdev = pci_info; 1708221167Sgnn 1709221167Sgnn err = vxge_alloc_bar_resources(vdev, 0); 1710221167Sgnn if (err != 0) { 1711221167Sgnn error_level = VXGE_FREE_BAR0; 1712221167Sgnn goto _exit0; 1713221167Sgnn } 1714221167Sgnn 1715221167Sgnn err = vxge_alloc_bar_resources(vdev, 1); 1716221167Sgnn if (err != 0) { 1717221167Sgnn error_level = VXGE_FREE_BAR1; 1718221167Sgnn goto _exit0; 1719221167Sgnn } 1720221167Sgnn 1721221167Sgnn err = vxge_alloc_bar_resources(vdev, 2); 1722221167Sgnn if (err != 0) 1723221167Sgnn error_level = VXGE_FREE_BAR2; 1724221167Sgnn 1725221167Sgnn_exit0: 1726221167Sgnn if (error_level) 1727221167Sgnn vxge_free_resources(ndev, error_level); 1728221167Sgnn 1729221167Sgnn return (err); 1730221167Sgnn} 1731221167Sgnn 1732221167Sgnn/* 1733221167Sgnn * vxge_alloc_bar_resources 1734221167Sgnn * Allocates BAR resources 1735221167Sgnn */ 1736221167Sgnnint 1737221167Sgnnvxge_alloc_bar_resources(vxge_dev_t *vdev, int i) 1738221167Sgnn{ 1739221167Sgnn int err = 0; 1740221167Sgnn int res_id = 0; 1741221167Sgnn vxge_pci_info_t *pci_info = vdev->pdev; 1742221167Sgnn 1743221167Sgnn res_id = PCIR_BAR((i == 0) ? 0 : (i * 2)); 1744221167Sgnn 1745221167Sgnn pci_info->bar_info[i] = 1746221167Sgnn bus_alloc_resource_any(vdev->ndev, 1747221167Sgnn SYS_RES_MEMORY, &res_id, RF_ACTIVE); 1748221167Sgnn 1749221167Sgnn if (pci_info->bar_info[i] == NULL) { 1750221167Sgnn device_printf(vdev->ndev, 1751221167Sgnn "failed to allocate memory for bus resources\n"); 1752221167Sgnn err = ENOMEM; 1753221167Sgnn goto _exit0; 1754221167Sgnn } 1755221167Sgnn 1756221167Sgnn pci_info->reg_map[i] = 1757221167Sgnn (vxge_bus_res_t *) vxge_mem_alloc(sizeof(vxge_bus_res_t)); 1758221167Sgnn 1759221167Sgnn if (pci_info->reg_map[i] == NULL) { 1760221167Sgnn device_printf(vdev->ndev, 1761221167Sgnn "failed to allocate memory bar resources\n"); 1762221167Sgnn err = ENOMEM; 1763221167Sgnn goto _exit0; 1764221167Sgnn } 1765221167Sgnn 1766221167Sgnn ((vxge_bus_res_t *) (pci_info->reg_map[i]))->bus_space_tag = 1767221167Sgnn rman_get_bustag(pci_info->bar_info[i]); 1768221167Sgnn 1769221167Sgnn ((vxge_bus_res_t *) (pci_info->reg_map[i]))->bus_space_handle = 1770221167Sgnn rman_get_bushandle(pci_info->bar_info[i]); 1771221167Sgnn 1772221167Sgnn ((vxge_bus_res_t *) (pci_info->reg_map[i]))->bar_start_addr = 1773221167Sgnn pci_info->bar_info[i]; 1774221167Sgnn 1775221167Sgnn ((vxge_bus_res_t *) (pci_info->reg_map[i]))->bus_res_len = 1776221167Sgnn rman_get_size(pci_info->bar_info[i]); 1777221167Sgnn 1778221167Sgnn_exit0: 1779221167Sgnn return (err); 1780221167Sgnn} 1781221167Sgnn 1782221167Sgnn/* 1783221167Sgnn * vxge_alloc_isr_resources 1784221167Sgnn */ 1785221167Sgnnint 1786221167Sgnnvxge_alloc_isr_resources(vxge_dev_t *vdev) 1787221167Sgnn{ 1788221167Sgnn int i, err = 0, irq_rid; 1789221167Sgnn int msix_vec_reqd, intr_count, msix_count; 1790221167Sgnn 1791221167Sgnn int intr_mode = VXGE_HAL_INTR_MODE_IRQLINE; 1792221167Sgnn 1793221167Sgnn if (vdev->config.intr_mode == VXGE_HAL_INTR_MODE_MSIX) { 1794221167Sgnn /* MSI-X messages supported by device */ 1795221167Sgnn intr_count = pci_msix_count(vdev->ndev); 1796221167Sgnn if (intr_count) { 1797221167Sgnn 1798221167Sgnn msix_vec_reqd = 4 * vdev->no_of_vpath; 1799221167Sgnn if (intr_count >= msix_vec_reqd) { 1800221167Sgnn intr_count = msix_vec_reqd; 1801221167Sgnn 1802221167Sgnn err = pci_alloc_msix(vdev->ndev, &intr_count); 1803221167Sgnn if (err == 0) 1804221167Sgnn intr_mode = VXGE_HAL_INTR_MODE_MSIX; 1805221167Sgnn } 1806221167Sgnn 1807221167Sgnn if ((err != 0) || (intr_count < msix_vec_reqd)) { 1808221167Sgnn device_printf(vdev->ndev, "Unable to allocate " 1809221167Sgnn "msi/x vectors switching to INTA mode\n"); 1810221167Sgnn } 1811221167Sgnn } 1812221167Sgnn } 1813221167Sgnn 1814221167Sgnn err = 0; 1815221167Sgnn vdev->intr_count = 0; 1816221167Sgnn vdev->config.intr_mode = intr_mode; 1817221167Sgnn 1818221167Sgnn switch (vdev->config.intr_mode) { 1819221167Sgnn case VXGE_HAL_INTR_MODE_IRQLINE: 1820221167Sgnn vdev->config.isr_info[0].irq_rid = 0; 1821221167Sgnn vdev->config.isr_info[0].irq_res = 1822221167Sgnn bus_alloc_resource_any(vdev->ndev, SYS_RES_IRQ, 1823221167Sgnn &vdev->config.isr_info[0].irq_rid, 1824221167Sgnn (RF_SHAREABLE | RF_ACTIVE)); 1825221167Sgnn 1826221167Sgnn if (vdev->config.isr_info[0].irq_res == NULL) { 1827221167Sgnn device_printf(vdev->ndev, 1828221167Sgnn "failed to allocate line interrupt resource\n"); 1829221167Sgnn err = ENOMEM; 1830221167Sgnn goto _exit0; 1831221167Sgnn } 1832221167Sgnn vdev->intr_count++; 1833221167Sgnn break; 1834221167Sgnn 1835221167Sgnn case VXGE_HAL_INTR_MODE_MSIX: 1836221167Sgnn msix_count = 0; 1837221167Sgnn for (i = 0; i < vdev->no_of_vpath; i++) { 1838221167Sgnn irq_rid = i * 4; 1839221167Sgnn 1840221167Sgnn vdev->config.isr_info[msix_count].irq_rid = irq_rid + 2; 1841221167Sgnn vdev->config.isr_info[msix_count].irq_res = 1842221167Sgnn bus_alloc_resource_any(vdev->ndev, SYS_RES_IRQ, 1843221167Sgnn &vdev->config.isr_info[msix_count].irq_rid, 1844221167Sgnn (RF_SHAREABLE | RF_ACTIVE)); 1845221167Sgnn 1846221167Sgnn if (vdev->config.isr_info[msix_count].irq_res == NULL) { 1847221167Sgnn device_printf(vdev->ndev, 1848221167Sgnn "allocating bus resource (rid %d) failed\n", 1849221167Sgnn vdev->config.isr_info[msix_count].irq_rid); 1850221167Sgnn err = ENOMEM; 1851221167Sgnn goto _exit0; 1852221167Sgnn } 1853221167Sgnn 1854221167Sgnn vdev->intr_count++; 1855221167Sgnn err = bus_bind_intr(vdev->ndev, 1856221167Sgnn vdev->config.isr_info[msix_count].irq_res, 1857221167Sgnn (i % mp_ncpus)); 1858221167Sgnn if (err != 0) 1859221167Sgnn break; 1860221167Sgnn 1861221167Sgnn msix_count++; 1862221167Sgnn } 1863221167Sgnn 1864221167Sgnn vdev->config.isr_info[msix_count].irq_rid = 3; 1865221167Sgnn vdev->config.isr_info[msix_count].irq_res = 1866221167Sgnn bus_alloc_resource_any(vdev->ndev, SYS_RES_IRQ, 1867221167Sgnn &vdev->config.isr_info[msix_count].irq_rid, 1868221167Sgnn (RF_SHAREABLE | RF_ACTIVE)); 1869221167Sgnn 1870221167Sgnn if (vdev->config.isr_info[msix_count].irq_res == NULL) { 1871221167Sgnn device_printf(vdev->ndev, 1872221167Sgnn "allocating bus resource (rid %d) failed\n", 1873221167Sgnn vdev->config.isr_info[msix_count].irq_rid); 1874221167Sgnn err = ENOMEM; 1875221167Sgnn goto _exit0; 1876221167Sgnn } 1877221167Sgnn 1878221167Sgnn vdev->intr_count++; 1879221167Sgnn err = bus_bind_intr(vdev->ndev, 1880221167Sgnn vdev->config.isr_info[msix_count].irq_res, (i % mp_ncpus)); 1881221167Sgnn 1882221167Sgnn break; 1883221167Sgnn } 1884221167Sgnn 1885221167Sgnn vdev->device_config->intr_mode = vdev->config.intr_mode; 1886221167Sgnn 1887221167Sgnn_exit0: 1888221167Sgnn return (err); 1889221167Sgnn} 1890221167Sgnn 1891221167Sgnn/* 1892221167Sgnn * vxge_free_resources 1893221167Sgnn * Undo what-all we did during load/attach 1894221167Sgnn */ 1895221167Sgnnvoid 1896221167Sgnnvxge_free_resources(device_t ndev, vxge_free_resources_e vxge_free_resource) 1897221167Sgnn{ 1898221167Sgnn int i; 1899221167Sgnn vxge_dev_t *vdev; 1900221167Sgnn 1901221167Sgnn vdev = (vxge_dev_t *) device_get_softc(ndev); 1902221167Sgnn 1903221167Sgnn switch (vxge_free_resource) { 1904221167Sgnn case VXGE_FREE_ALL: 1905221167Sgnn for (i = 0; i < vdev->intr_count; i++) { 1906221167Sgnn bus_teardown_intr(ndev, 1907221167Sgnn vdev->config.isr_info[i].irq_res, 1908221167Sgnn vdev->config.isr_info[i].irq_handle); 1909221167Sgnn } 1910221167Sgnn /* FALLTHROUGH */ 1911221167Sgnn 1912221167Sgnn case VXGE_FREE_INTERFACE: 1913221167Sgnn ether_ifdetach(vdev->ifp); 1914221167Sgnn bus_generic_detach(ndev); 1915221167Sgnn if_free(vdev->ifp); 1916221167Sgnn /* FALLTHROUGH */ 1917221167Sgnn 1918221167Sgnn case VXGE_FREE_MEDIA: 1919221167Sgnn ifmedia_removeall(&vdev->media); 1920221167Sgnn /* FALLTHROUGH */ 1921221167Sgnn 1922221167Sgnn case VXGE_FREE_MUTEX: 1923221167Sgnn vxge_mutex_destroy(vdev); 1924221167Sgnn /* FALLTHROUGH */ 1925221167Sgnn 1926221167Sgnn case VXGE_FREE_VPATH: 1927221167Sgnn vxge_mem_free(vdev->vpaths, 1928221167Sgnn vdev->no_of_vpath * sizeof(vxge_vpath_t)); 1929221167Sgnn /* FALLTHROUGH */ 1930221167Sgnn 1931221167Sgnn case VXGE_FREE_TERMINATE_DEVICE: 1932221167Sgnn if (vdev->devh != NULL) { 1933221167Sgnn vxge_hal_device_private_set(vdev->devh, 0); 1934221167Sgnn vxge_hal_device_terminate(vdev->devh); 1935221167Sgnn } 1936221167Sgnn /* FALLTHROUGH */ 1937221167Sgnn 1938221167Sgnn case VXGE_FREE_ISR_RESOURCE: 1939221167Sgnn vxge_free_isr_resources(vdev); 1940221167Sgnn /* FALLTHROUGH */ 1941221167Sgnn 1942221167Sgnn case VXGE_FREE_BAR2: 1943221167Sgnn vxge_free_bar_resources(vdev, 2); 1944221167Sgnn /* FALLTHROUGH */ 1945221167Sgnn 1946221167Sgnn case VXGE_FREE_BAR1: 1947221167Sgnn vxge_free_bar_resources(vdev, 1); 1948221167Sgnn /* FALLTHROUGH */ 1949221167Sgnn 1950221167Sgnn case VXGE_FREE_BAR0: 1951221167Sgnn vxge_free_bar_resources(vdev, 0); 1952221167Sgnn /* FALLTHROUGH */ 1953221167Sgnn 1954221167Sgnn case VXGE_FREE_PCI_INFO: 1955221167Sgnn vxge_mem_free(vdev->pdev, sizeof(vxge_pci_info_t)); 1956221167Sgnn /* FALLTHROUGH */ 1957221167Sgnn 1958221167Sgnn case VXGE_FREE_DEVICE_CONFIG: 1959221167Sgnn vxge_mem_free(vdev->device_config, 1960221167Sgnn sizeof(vxge_hal_device_config_t)); 1961221167Sgnn /* FALLTHROUGH */ 1962221167Sgnn 1963221167Sgnn case VXGE_DISABLE_PCI_BUSMASTER: 1964221167Sgnn pci_disable_busmaster(ndev); 1965221167Sgnn /* FALLTHROUGH */ 1966221167Sgnn 1967221167Sgnn case VXGE_FREE_TERMINATE_DRIVER: 1968221167Sgnn if (vxge_dev_ref_count) { 1969221167Sgnn --vxge_dev_ref_count; 1970221167Sgnn if (0 == vxge_dev_ref_count) 1971221167Sgnn vxge_hal_driver_terminate(); 1972221167Sgnn } 1973221167Sgnn /* FALLTHROUGH */ 1974221167Sgnn 1975221167Sgnn default: 1976221167Sgnn case VXGE_FREE_NONE: 1977221167Sgnn break; 1978221167Sgnn /* NOTREACHED */ 1979221167Sgnn } 1980221167Sgnn} 1981221167Sgnn 1982221167Sgnnvoid 1983221167Sgnnvxge_free_isr_resources(vxge_dev_t *vdev) 1984221167Sgnn{ 1985221167Sgnn int i; 1986221167Sgnn 1987221167Sgnn switch (vdev->config.intr_mode) { 1988221167Sgnn case VXGE_HAL_INTR_MODE_IRQLINE: 1989221167Sgnn if (vdev->config.isr_info[0].irq_res) { 1990221167Sgnn bus_release_resource(vdev->ndev, SYS_RES_IRQ, 1991221167Sgnn vdev->config.isr_info[0].irq_rid, 1992221167Sgnn vdev->config.isr_info[0].irq_res); 1993221167Sgnn 1994221167Sgnn vdev->config.isr_info[0].irq_res = NULL; 1995221167Sgnn } 1996221167Sgnn break; 1997221167Sgnn 1998221167Sgnn case VXGE_HAL_INTR_MODE_MSIX: 1999221167Sgnn for (i = 0; i < vdev->intr_count; i++) { 2000221167Sgnn if (vdev->config.isr_info[i].irq_res) { 2001221167Sgnn bus_release_resource(vdev->ndev, SYS_RES_IRQ, 2002221167Sgnn vdev->config.isr_info[i].irq_rid, 2003221167Sgnn vdev->config.isr_info[i].irq_res); 2004221167Sgnn 2005221167Sgnn vdev->config.isr_info[i].irq_res = NULL; 2006221167Sgnn } 2007221167Sgnn } 2008221167Sgnn 2009221167Sgnn if (vdev->intr_count) 2010221167Sgnn pci_release_msi(vdev->ndev); 2011221167Sgnn 2012221167Sgnn break; 2013221167Sgnn } 2014221167Sgnn} 2015221167Sgnn 2016221167Sgnnvoid 2017221167Sgnnvxge_free_bar_resources(vxge_dev_t *vdev, int i) 2018221167Sgnn{ 2019221167Sgnn int res_id = 0; 2020221167Sgnn vxge_pci_info_t *pci_info = vdev->pdev; 2021221167Sgnn 2022221167Sgnn res_id = PCIR_BAR((i == 0) ? 0 : (i * 2)); 2023221167Sgnn 2024221167Sgnn if (pci_info->bar_info[i]) 2025221167Sgnn bus_release_resource(vdev->ndev, SYS_RES_MEMORY, 2026221167Sgnn res_id, pci_info->bar_info[i]); 2027221167Sgnn 2028221167Sgnn vxge_mem_free(pci_info->reg_map[i], sizeof(vxge_bus_res_t)); 2029221167Sgnn} 2030221167Sgnn 2031221167Sgnn/* 2032221167Sgnn * vxge_init_mutex 2033221167Sgnn * Initializes mutexes used in driver 2034221167Sgnn */ 2035221167Sgnnvoid 2036221167Sgnnvxge_mutex_init(vxge_dev_t *vdev) 2037221167Sgnn{ 2038221167Sgnn int i; 2039221167Sgnn 2040221167Sgnn snprintf(vdev->mtx_drv_name, sizeof(vdev->mtx_drv_name), 2041221167Sgnn "%s_drv", vdev->ndev_name); 2042221167Sgnn 2043221167Sgnn mtx_init(&vdev->mtx_drv, vdev->mtx_drv_name, 2044221167Sgnn MTX_NETWORK_LOCK, MTX_DEF); 2045221167Sgnn 2046221167Sgnn for (i = 0; i < vdev->no_of_vpath; i++) { 2047221167Sgnn snprintf(vdev->vpaths[i].mtx_tx_name, 2048221167Sgnn sizeof(vdev->vpaths[i].mtx_tx_name), "%s_tx_%d", 2049221167Sgnn vdev->ndev_name, i); 2050221167Sgnn 2051221167Sgnn mtx_init(&vdev->vpaths[i].mtx_tx, 2052221167Sgnn vdev->vpaths[i].mtx_tx_name, NULL, MTX_DEF); 2053221167Sgnn } 2054221167Sgnn} 2055221167Sgnn 2056221167Sgnn/* 2057221167Sgnn * vxge_mutex_destroy 2058221167Sgnn * Destroys mutexes used in driver 2059221167Sgnn */ 2060221167Sgnnvoid 2061221167Sgnnvxge_mutex_destroy(vxge_dev_t *vdev) 2062221167Sgnn{ 2063221167Sgnn int i; 2064221167Sgnn 2065221167Sgnn for (i = 0; i < vdev->no_of_vpath; i++) 2066221167Sgnn VXGE_TX_LOCK_DESTROY(&(vdev->vpaths[i])); 2067221167Sgnn 2068221167Sgnn VXGE_DRV_LOCK_DESTROY(vdev); 2069221167Sgnn} 2070221167Sgnn 2071221167Sgnn/* 2072221167Sgnn * vxge_rth_config 2073221167Sgnn */ 2074221167Sgnnvxge_hal_status_e 2075221167Sgnnvxge_rth_config(vxge_dev_t *vdev) 2076221167Sgnn{ 2077221167Sgnn int i; 2078221167Sgnn vxge_hal_vpath_h vpath_handle; 2079221167Sgnn vxge_hal_rth_hash_types_t hash_types; 2080221167Sgnn vxge_hal_status_e status = VXGE_HAL_OK; 2081221167Sgnn u8 mtable[256] = {0}; 2082221167Sgnn 2083221167Sgnn /* Filling matable with bucket-to-vpath mapping */ 2084221167Sgnn vdev->config.rth_bkt_sz = VXGE_DEFAULT_RTH_BUCKET_SIZE; 2085221167Sgnn 2086221167Sgnn for (i = 0; i < (1 << vdev->config.rth_bkt_sz); i++) 2087221167Sgnn mtable[i] = i % vdev->no_of_vpath; 2088221167Sgnn 2089221167Sgnn /* Fill RTH hash types */ 2090221167Sgnn hash_types.hash_type_tcpipv4_en = VXGE_HAL_RING_HASH_TYPE_TCP_IPV4; 2091221167Sgnn hash_types.hash_type_tcpipv6_en = VXGE_HAL_RING_HASH_TYPE_TCP_IPV6; 2092221167Sgnn hash_types.hash_type_tcpipv6ex_en = VXGE_HAL_RING_HASH_TYPE_TCP_IPV6_EX; 2093221167Sgnn hash_types.hash_type_ipv4_en = VXGE_HAL_RING_HASH_TYPE_IPV4; 2094221167Sgnn hash_types.hash_type_ipv6_en = VXGE_HAL_RING_HASH_TYPE_IPV6; 2095221167Sgnn hash_types.hash_type_ipv6ex_en = VXGE_HAL_RING_HASH_TYPE_IPV6_EX; 2096221167Sgnn 2097221167Sgnn /* set indirection table, bucket-to-vpath mapping */ 2098221167Sgnn status = vxge_hal_vpath_rts_rth_itable_set(vdev->vpath_handles, 2099221167Sgnn vdev->no_of_vpath, mtable, 2100221167Sgnn ((u32) (1 << vdev->config.rth_bkt_sz))); 2101221167Sgnn 2102221167Sgnn if (status != VXGE_HAL_OK) { 2103221167Sgnn device_printf(vdev->ndev, "rth configuration failed\n"); 2104221167Sgnn goto _exit0; 2105221167Sgnn } 2106221167Sgnn for (i = 0; i < vdev->no_of_vpath; i++) { 2107221167Sgnn vpath_handle = vxge_vpath_handle_get(vdev, i); 2108221167Sgnn if (!vpath_handle) 2109221167Sgnn continue; 2110221167Sgnn 2111221167Sgnn status = vxge_hal_vpath_rts_rth_set(vpath_handle, 2112221167Sgnn RTH_ALG_JENKINS, 2113221167Sgnn &hash_types, vdev->config.rth_bkt_sz, TRUE); 2114221167Sgnn if (status != VXGE_HAL_OK) { 2115221167Sgnn device_printf(vdev->ndev, 2116221167Sgnn "rth configuration failed for vpath (%d)\n", 2117221167Sgnn vdev->vpaths[i].vp_id); 2118221167Sgnn break; 2119221167Sgnn } 2120221167Sgnn } 2121221167Sgnn 2122221167Sgnn_exit0: 2123221167Sgnn return (status); 2124221167Sgnn} 2125221167Sgnn 2126221167Sgnn/* 2127221167Sgnn * vxge_vpath_config 2128221167Sgnn * Sets HAL parameter values from kenv 2129221167Sgnn */ 2130221167Sgnnvoid 2131221167Sgnnvxge_vpath_config(vxge_dev_t *vdev) 2132221167Sgnn{ 2133221167Sgnn int i; 2134221167Sgnn u32 no_of_vpath = 0; 2135221167Sgnn vxge_hal_vp_config_t *vp_config; 2136221167Sgnn vxge_hal_device_config_t *device_config = vdev->device_config; 2137221167Sgnn 2138221167Sgnn device_config->debug_level = VXGE_TRACE; 2139221167Sgnn device_config->debug_mask = VXGE_COMPONENT_ALL; 2140221167Sgnn device_config->device_poll_millis = VXGE_DEFAULT_DEVICE_POLL_MILLIS; 2141221167Sgnn 2142221167Sgnn vdev->config.no_of_vpath = 2143221167Sgnn min(vdev->config.no_of_vpath, vdev->max_supported_vpath); 2144221167Sgnn 2145221167Sgnn for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) { 2146221167Sgnn vp_config = &(device_config->vp_config[i]); 2147221167Sgnn vp_config->fifo.enable = VXGE_HAL_FIFO_DISABLE; 2148221167Sgnn vp_config->ring.enable = VXGE_HAL_RING_DISABLE; 2149221167Sgnn } 2150221167Sgnn 2151221167Sgnn for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) { 2152221167Sgnn if (no_of_vpath >= vdev->config.no_of_vpath) 2153221167Sgnn break; 2154221167Sgnn 2155221167Sgnn if (!bVAL1(vdev->config.hw_info.vpath_mask, i)) 2156221167Sgnn continue; 2157221167Sgnn 2158221167Sgnn no_of_vpath++; 2159221167Sgnn vp_config = &(device_config->vp_config[i]); 2160221167Sgnn vp_config->mtu = VXGE_HAL_DEFAULT_MTU; 2161221167Sgnn vp_config->ring.enable = VXGE_HAL_RING_ENABLE; 2162221167Sgnn vp_config->ring.post_mode = VXGE_HAL_RING_POST_MODE_DOORBELL; 2163221167Sgnn vp_config->ring.buffer_mode = VXGE_HAL_RING_RXD_BUFFER_MODE_1; 2164221167Sgnn vp_config->ring.ring_length = 2165221167Sgnn vxge_ring_length_get(VXGE_HAL_RING_RXD_BUFFER_MODE_1); 2166221167Sgnn vp_config->ring.scatter_mode = VXGE_HAL_RING_SCATTER_MODE_A; 2167221167Sgnn vp_config->rpa_all_vid_en = VXGE_DEFAULT_ALL_VID_ENABLE; 2168221167Sgnn vp_config->rpa_strip_vlan_tag = VXGE_DEFAULT_STRIP_VLAN_TAG; 2169221167Sgnn vp_config->rpa_ucast_all_addr_en = 2170221167Sgnn VXGE_HAL_VPATH_RPA_UCAST_ALL_ADDR_DISABLE; 2171221167Sgnn 2172221167Sgnn vp_config->rti.intr_enable = VXGE_HAL_TIM_INTR_ENABLE; 2173221167Sgnn vp_config->rti.txfrm_cnt_en = VXGE_HAL_TXFRM_CNT_EN_ENABLE; 2174221167Sgnn vp_config->rti.util_sel = 2175221167Sgnn VXGE_HAL_TIM_UTIL_SEL_LEGACY_RX_NET_UTIL; 2176221167Sgnn 2177221167Sgnn vp_config->rti.uec_a = VXGE_DEFAULT_RTI_RX_UFC_A; 2178221167Sgnn vp_config->rti.uec_b = VXGE_DEFAULT_RTI_RX_UFC_B; 2179221167Sgnn vp_config->rti.uec_c = VXGE_DEFAULT_RTI_RX_UFC_C; 2180221167Sgnn vp_config->rti.uec_d = VXGE_DEFAULT_RTI_RX_UFC_D; 2181221167Sgnn 2182221167Sgnn vp_config->rti.urange_a = VXGE_DEFAULT_RTI_RX_URANGE_A; 2183221167Sgnn vp_config->rti.urange_b = VXGE_DEFAULT_RTI_RX_URANGE_B; 2184221167Sgnn vp_config->rti.urange_c = VXGE_DEFAULT_RTI_RX_URANGE_C; 2185221167Sgnn 2186221167Sgnn vp_config->rti.timer_ac_en = VXGE_HAL_TIM_TIMER_AC_ENABLE; 2187221167Sgnn vp_config->rti.timer_ci_en = VXGE_HAL_TIM_TIMER_CI_ENABLE; 2188221167Sgnn 2189221167Sgnn vp_config->rti.btimer_val = 2190221167Sgnn (VXGE_DEFAULT_RTI_BTIMER_VAL * 1000) / 272; 2191221167Sgnn vp_config->rti.rtimer_val = 2192221167Sgnn (VXGE_DEFAULT_RTI_RTIMER_VAL * 1000) / 272; 2193221167Sgnn vp_config->rti.ltimer_val = 2194221167Sgnn (VXGE_DEFAULT_RTI_LTIMER_VAL * 1000) / 272; 2195221167Sgnn 2196221167Sgnn if ((no_of_vpath > 1) && (VXGE_DEFAULT_CONFIG_MQ_ENABLE == 0)) 2197221167Sgnn continue; 2198221167Sgnn 2199221167Sgnn vp_config->fifo.enable = VXGE_HAL_FIFO_ENABLE; 2200221167Sgnn vp_config->fifo.max_aligned_frags = 2201221167Sgnn VXGE_DEFAULT_FIFO_ALIGNED_FRAGS; 2202221167Sgnn 2203221167Sgnn vp_config->tti.intr_enable = VXGE_HAL_TIM_INTR_ENABLE; 2204221167Sgnn vp_config->tti.txfrm_cnt_en = VXGE_HAL_TXFRM_CNT_EN_ENABLE; 2205221167Sgnn vp_config->tti.util_sel = 2206221167Sgnn VXGE_HAL_TIM_UTIL_SEL_LEGACY_TX_NET_UTIL; 2207221167Sgnn 2208221167Sgnn vp_config->tti.uec_a = VXGE_DEFAULT_TTI_TX_UFC_A; 2209221167Sgnn vp_config->tti.uec_b = VXGE_DEFAULT_TTI_TX_UFC_B; 2210221167Sgnn vp_config->tti.uec_c = VXGE_DEFAULT_TTI_TX_UFC_C; 2211221167Sgnn vp_config->tti.uec_d = VXGE_DEFAULT_TTI_TX_UFC_D; 2212221167Sgnn 2213221167Sgnn vp_config->tti.urange_a = VXGE_DEFAULT_TTI_TX_URANGE_A; 2214221167Sgnn vp_config->tti.urange_b = VXGE_DEFAULT_TTI_TX_URANGE_B; 2215221167Sgnn vp_config->tti.urange_c = VXGE_DEFAULT_TTI_TX_URANGE_C; 2216221167Sgnn 2217221167Sgnn vp_config->tti.timer_ac_en = VXGE_HAL_TIM_TIMER_AC_ENABLE; 2218221167Sgnn vp_config->tti.timer_ci_en = VXGE_HAL_TIM_TIMER_CI_ENABLE; 2219221167Sgnn 2220221167Sgnn vp_config->tti.btimer_val = 2221221167Sgnn (VXGE_DEFAULT_TTI_BTIMER_VAL * 1000) / 272; 2222221167Sgnn vp_config->tti.rtimer_val = 2223221167Sgnn (VXGE_DEFAULT_TTI_RTIMER_VAL * 1000) / 272; 2224221167Sgnn vp_config->tti.ltimer_val = 2225221167Sgnn (VXGE_DEFAULT_TTI_LTIMER_VAL * 1000) / 272; 2226221167Sgnn } 2227221167Sgnn 2228221167Sgnn vdev->no_of_vpath = no_of_vpath; 2229221167Sgnn 2230221167Sgnn if (vdev->no_of_vpath == 1) 2231221167Sgnn vdev->config.tx_steering = 0; 2232221167Sgnn 2233221167Sgnn if (vdev->config.rth_enable && (vdev->no_of_vpath > 1)) { 2234221167Sgnn device_config->rth_en = VXGE_HAL_RTH_ENABLE; 2235221167Sgnn device_config->rth_it_type = VXGE_HAL_RTH_IT_TYPE_MULTI_IT; 2236221167Sgnn } 2237221167Sgnn 2238221167Sgnn vdev->config.rth_enable = device_config->rth_en; 2239221167Sgnn} 2240221167Sgnn 2241221167Sgnn/* 2242221167Sgnn * vxge_vpath_cb_fn 2243221167Sgnn * Virtual path Callback function 2244221167Sgnn */ 2245221167Sgnn/* ARGSUSED */ 2246221167Sgnnstatic vxge_hal_status_e 2247221167Sgnnvxge_vpath_cb_fn(vxge_hal_client_h client_handle, vxge_hal_up_msg_h msgh, 2248221167Sgnn vxge_hal_message_type_e msg_type, vxge_hal_obj_id_t obj_id, 2249221167Sgnn vxge_hal_result_e result, vxge_hal_opaque_handle_t *opaque_handle) 2250221167Sgnn{ 2251221167Sgnn return (VXGE_HAL_OK); 2252221167Sgnn} 2253221167Sgnn 2254221167Sgnn/* 2255221167Sgnn * vxge_vpath_open 2256221167Sgnn */ 2257221167Sgnnint 2258221167Sgnnvxge_vpath_open(vxge_dev_t *vdev) 2259221167Sgnn{ 2260221167Sgnn int i, err = EINVAL; 2261221167Sgnn u64 func_id; 2262221167Sgnn 2263221167Sgnn vxge_vpath_t *vpath; 2264221167Sgnn vxge_hal_vpath_attr_t vpath_attr; 2265221167Sgnn vxge_hal_status_e status = VXGE_HAL_OK; 2266221167Sgnn struct lro_ctrl *lro = NULL; 2267221167Sgnn 2268221167Sgnn bzero(&vpath_attr, sizeof(vxge_hal_vpath_attr_t)); 2269221167Sgnn 2270221167Sgnn for (i = 0; i < vdev->no_of_vpath; i++) { 2271221167Sgnn 2272221167Sgnn vpath = &(vdev->vpaths[i]); 2273221167Sgnn lro = &vpath->lro; 2274221167Sgnn 2275221167Sgnn /* Vpath vpath_attr: FIFO */ 2276221167Sgnn vpath_attr.vp_id = vpath->vp_id; 2277221167Sgnn vpath_attr.fifo_attr.callback = vxge_tx_compl; 2278221167Sgnn vpath_attr.fifo_attr.txdl_init = vxge_tx_replenish; 2279221167Sgnn vpath_attr.fifo_attr.txdl_term = vxge_tx_term; 2280221167Sgnn vpath_attr.fifo_attr.userdata = vpath; 2281221167Sgnn vpath_attr.fifo_attr.per_txdl_space = sizeof(vxge_txdl_priv_t); 2282221167Sgnn 2283221167Sgnn /* Vpath vpath_attr: Ring */ 2284221167Sgnn vpath_attr.ring_attr.callback = vxge_rx_compl; 2285221167Sgnn vpath_attr.ring_attr.rxd_init = vxge_rx_replenish; 2286221167Sgnn vpath_attr.ring_attr.rxd_term = vxge_rx_term; 2287221167Sgnn vpath_attr.ring_attr.userdata = vpath; 2288221167Sgnn vpath_attr.ring_attr.per_rxd_space = sizeof(vxge_rxd_priv_t); 2289221167Sgnn 2290221167Sgnn err = vxge_dma_tags_create(vpath); 2291221167Sgnn if (err != 0) { 2292221167Sgnn device_printf(vdev->ndev, 2293221167Sgnn "failed to create dma tags\n"); 2294221167Sgnn break; 2295221167Sgnn } 2296221167Sgnn#if __FreeBSD_version >= 800000 2297221167Sgnn vpath->br = buf_ring_alloc(VXGE_DEFAULT_BR_SIZE, M_DEVBUF, 2298221167Sgnn M_WAITOK, &vpath->mtx_tx); 2299221167Sgnn if (vpath->br == NULL) { 2300221167Sgnn err = ENOMEM; 2301221167Sgnn break; 2302221167Sgnn } 2303221167Sgnn#endif 2304221167Sgnn status = vxge_hal_vpath_open(vdev->devh, &vpath_attr, 2305221167Sgnn (vxge_hal_vpath_callback_f) vxge_vpath_cb_fn, 2306221167Sgnn NULL, &vpath->handle); 2307221167Sgnn if (status != VXGE_HAL_OK) { 2308221167Sgnn device_printf(vdev->ndev, 2309221167Sgnn "failed to open vpath (%d)\n", vpath->vp_id); 2310221167Sgnn err = EPERM; 2311221167Sgnn break; 2312221167Sgnn } 2313221167Sgnn vpath->is_open = TRUE; 2314221167Sgnn vdev->vpath_handles[i] = vpath->handle; 2315221167Sgnn 2316221167Sgnn vpath->tx_ticks = ticks; 2317221167Sgnn vpath->rx_ticks = ticks; 2318221167Sgnn 2319221167Sgnn vpath->tti_rtimer_val = VXGE_DEFAULT_TTI_RTIMER_VAL; 2320221167Sgnn vpath->tti_rtimer_val = VXGE_DEFAULT_TTI_RTIMER_VAL; 2321221167Sgnn 2322221167Sgnn vpath->tx_intr_coalesce = vdev->config.intr_coalesce; 2323221167Sgnn vpath->rx_intr_coalesce = vdev->config.intr_coalesce; 2324221167Sgnn 2325221167Sgnn func_id = vdev->config.hw_info.func_id; 2326221167Sgnn 2327221167Sgnn if (vdev->config.low_latency && 2328221167Sgnn (vdev->config.bw_info[func_id].priority == 2329221167Sgnn VXGE_DEFAULT_VPATH_PRIORITY_HIGH)) { 2330221167Sgnn vpath->tx_intr_coalesce = 0; 2331221167Sgnn } 2332221167Sgnn 2333221167Sgnn if (vdev->ifp->if_capenable & IFCAP_LRO) { 2334221167Sgnn err = tcp_lro_init(lro); 2335221167Sgnn if (err != 0) { 2336221167Sgnn device_printf(vdev->ndev, 2337221167Sgnn "LRO Initialization failed!\n"); 2338221167Sgnn break; 2339221167Sgnn } 2340221167Sgnn vpath->lro_enable = TRUE; 2341221167Sgnn lro->ifp = vdev->ifp; 2342221167Sgnn } 2343221167Sgnn } 2344221167Sgnn 2345221167Sgnn return (err); 2346221167Sgnn} 2347221167Sgnn 2348221167Sgnnvoid 2349221167Sgnnvxge_tso_config(vxge_dev_t *vdev) 2350221167Sgnn{ 2351221167Sgnn u32 func_id, priority; 2352221167Sgnn vxge_hal_status_e status = VXGE_HAL_OK; 2353221167Sgnn 2354221167Sgnn vdev->ifp->if_capabilities |= IFCAP_TSO4; 2355221167Sgnn 2356221167Sgnn status = vxge_bw_priority_get(vdev, NULL); 2357221167Sgnn if (status == VXGE_HAL_OK) { 2358221167Sgnn 2359221167Sgnn func_id = vdev->config.hw_info.func_id; 2360221167Sgnn priority = vdev->config.bw_info[func_id].priority; 2361221167Sgnn 2362221167Sgnn if (priority != VXGE_DEFAULT_VPATH_PRIORITY_HIGH) 2363221167Sgnn vdev->ifp->if_capabilities &= ~IFCAP_TSO4; 2364221167Sgnn } 2365221167Sgnn 2366221167Sgnn#if __FreeBSD_version >= 800000 2367221167Sgnn if (vdev->ifp->if_capabilities & IFCAP_TSO4) 2368221167Sgnn vdev->ifp->if_capabilities |= IFCAP_VLAN_HWTSO; 2369221167Sgnn#endif 2370221167Sgnn 2371221167Sgnn} 2372221167Sgnn 2373221167Sgnnvxge_hal_status_e 2374221167Sgnnvxge_bw_priority_get(vxge_dev_t *vdev, vxge_bw_info_t *bw_info) 2375221167Sgnn{ 2376221167Sgnn u32 priority, bandwidth; 2377221167Sgnn u32 vpath_count; 2378221167Sgnn 2379221167Sgnn u64 func_id, func_mode, vpath_list[VXGE_HAL_MAX_VIRTUAL_PATHS]; 2380221167Sgnn vxge_hal_status_e status = VXGE_HAL_OK; 2381221167Sgnn 2382221167Sgnn func_id = vdev->config.hw_info.func_id; 2383221167Sgnn if (bw_info) { 2384221167Sgnn func_id = bw_info->func_id; 2385221167Sgnn func_mode = vdev->config.hw_info.function_mode; 2386221167Sgnn if ((is_single_func(func_mode)) && (func_id > 0)) 2387221167Sgnn return (VXGE_HAL_FAIL); 2388221167Sgnn } 2389221167Sgnn 2390221167Sgnn if (vdev->hw_fw_version >= VXGE_FW_VERSION(1, 8, 0)) { 2391221167Sgnn 2392221167Sgnn status = vxge_hal_vf_rx_bw_get(vdev->devh, 2393221167Sgnn func_id, &bandwidth, &priority); 2394221167Sgnn 2395221167Sgnn } else { 2396221167Sgnn 2397221167Sgnn status = vxge_hal_get_vpath_list(vdev->devh, 2398221167Sgnn func_id, vpath_list, &vpath_count); 2399221167Sgnn 2400221167Sgnn if (status == VXGE_HAL_OK) { 2401221167Sgnn status = vxge_hal_bw_priority_get(vdev->devh, 2402221167Sgnn vpath_list[0], &bandwidth, &priority); 2403221167Sgnn } 2404221167Sgnn } 2405221167Sgnn 2406221167Sgnn if (status == VXGE_HAL_OK) { 2407221167Sgnn if (bw_info) { 2408221167Sgnn bw_info->priority = priority; 2409221167Sgnn bw_info->bandwidth = bandwidth; 2410221167Sgnn } else { 2411221167Sgnn vdev->config.bw_info[func_id].priority = priority; 2412221167Sgnn vdev->config.bw_info[func_id].bandwidth = bandwidth; 2413221167Sgnn } 2414221167Sgnn } 2415221167Sgnn 2416221167Sgnn return (status); 2417221167Sgnn} 2418221167Sgnn 2419221167Sgnn/* 2420221167Sgnn * close vpaths 2421221167Sgnn */ 2422221167Sgnnvoid 2423221167Sgnnvxge_vpath_close(vxge_dev_t *vdev) 2424221167Sgnn{ 2425221167Sgnn int i; 2426221167Sgnn vxge_vpath_t *vpath; 2427221167Sgnn 2428221167Sgnn for (i = 0; i < vdev->no_of_vpath; i++) { 2429221167Sgnn 2430221167Sgnn vpath = &(vdev->vpaths[i]); 2431221167Sgnn if (vpath->handle) 2432221167Sgnn vxge_hal_vpath_close(vpath->handle); 2433221167Sgnn 2434221167Sgnn#if __FreeBSD_version >= 800000 2435221167Sgnn if (vpath->br != NULL) 2436221167Sgnn buf_ring_free(vpath->br, M_DEVBUF); 2437221167Sgnn#endif 2438221167Sgnn /* Free LRO memory */ 2439221167Sgnn if (vpath->lro_enable) 2440221167Sgnn tcp_lro_free(&vpath->lro); 2441221167Sgnn 2442221167Sgnn if (vpath->dma_tag_rx) { 2443221167Sgnn bus_dmamap_destroy(vpath->dma_tag_rx, 2444221167Sgnn vpath->extra_dma_map); 2445221167Sgnn bus_dma_tag_destroy(vpath->dma_tag_rx); 2446221167Sgnn } 2447221167Sgnn 2448221167Sgnn if (vpath->dma_tag_tx) 2449221167Sgnn bus_dma_tag_destroy(vpath->dma_tag_tx); 2450221167Sgnn 2451221167Sgnn vpath->handle = NULL; 2452221167Sgnn vpath->is_open = FALSE; 2453221167Sgnn } 2454221167Sgnn} 2455221167Sgnn 2456221167Sgnn/* 2457221167Sgnn * reset vpaths 2458221167Sgnn */ 2459221167Sgnnvoid 2460221167Sgnnvxge_vpath_reset(vxge_dev_t *vdev) 2461221167Sgnn{ 2462221167Sgnn int i; 2463221167Sgnn vxge_hal_vpath_h vpath_handle; 2464221167Sgnn vxge_hal_status_e status = VXGE_HAL_OK; 2465221167Sgnn 2466221167Sgnn for (i = 0; i < vdev->no_of_vpath; i++) { 2467221167Sgnn vpath_handle = vxge_vpath_handle_get(vdev, i); 2468221167Sgnn if (!vpath_handle) 2469221167Sgnn continue; 2470221167Sgnn 2471221167Sgnn status = vxge_hal_vpath_reset(vpath_handle); 2472221167Sgnn if (status != VXGE_HAL_OK) 2473221167Sgnn device_printf(vdev->ndev, 2474221167Sgnn "failed to reset vpath :%d\n", i); 2475221167Sgnn } 2476221167Sgnn} 2477221167Sgnn 2478221167Sgnnstatic inline int 2479221167Sgnnvxge_vpath_get(vxge_dev_t *vdev, mbuf_t mhead) 2480221167Sgnn{ 2481221167Sgnn struct tcphdr *th = NULL; 2482221167Sgnn struct udphdr *uh = NULL; 2483221167Sgnn struct ip *ip = NULL; 2484221167Sgnn struct ip6_hdr *ip6 = NULL; 2485221167Sgnn struct ether_vlan_header *eth = NULL; 2486221167Sgnn void *ulp = NULL; 2487221167Sgnn 2488221167Sgnn int ehdrlen, iphlen = 0; 2489221167Sgnn u8 ipproto = 0; 2490221167Sgnn u16 etype, src_port, dst_port; 2491221167Sgnn u16 queue_len, counter = 0; 2492221167Sgnn 2493221167Sgnn src_port = dst_port = 0; 2494221167Sgnn queue_len = vdev->no_of_vpath; 2495221167Sgnn 2496221167Sgnn eth = mtod(mhead, struct ether_vlan_header *); 2497221167Sgnn if (eth->evl_encap_proto == htons(ETHERTYPE_VLAN)) { 2498221167Sgnn etype = ntohs(eth->evl_proto); 2499221167Sgnn ehdrlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN; 2500221167Sgnn } else { 2501221167Sgnn etype = ntohs(eth->evl_encap_proto); 2502221167Sgnn ehdrlen = ETHER_HDR_LEN; 2503221167Sgnn } 2504221167Sgnn 2505221167Sgnn switch (etype) { 2506221167Sgnn case ETHERTYPE_IP: 2507221167Sgnn ip = (struct ip *) (mhead->m_data + ehdrlen); 2508221167Sgnn iphlen = ip->ip_hl << 2; 2509221167Sgnn ipproto = ip->ip_p; 2510221167Sgnn th = (struct tcphdr *) ((caddr_t)ip + iphlen); 2511221167Sgnn uh = (struct udphdr *) ((caddr_t)ip + iphlen); 2512221167Sgnn break; 2513221167Sgnn 2514221167Sgnn case ETHERTYPE_IPV6: 2515221167Sgnn ip6 = (struct ip6_hdr *) (mhead->m_data + ehdrlen); 2516221167Sgnn iphlen = sizeof(struct ip6_hdr); 2517221167Sgnn ipproto = ip6->ip6_nxt; 2518221167Sgnn 2519221167Sgnn ulp = mtod(mhead, char *) + iphlen; 2520221167Sgnn th = ((struct tcphdr *) (ulp)); 2521221167Sgnn uh = ((struct udphdr *) (ulp)); 2522221167Sgnn break; 2523221167Sgnn 2524221167Sgnn default: 2525221167Sgnn break; 2526221167Sgnn } 2527221167Sgnn 2528221167Sgnn switch (ipproto) { 2529221167Sgnn case IPPROTO_TCP: 2530221167Sgnn src_port = th->th_sport; 2531221167Sgnn dst_port = th->th_dport; 2532221167Sgnn break; 2533221167Sgnn 2534221167Sgnn case IPPROTO_UDP: 2535221167Sgnn src_port = uh->uh_sport; 2536221167Sgnn dst_port = uh->uh_dport; 2537221167Sgnn break; 2538221167Sgnn 2539221167Sgnn default: 2540221167Sgnn break; 2541221167Sgnn } 2542221167Sgnn 2543221167Sgnn counter = (ntohs(src_port) + ntohs(dst_port)) & 2544221167Sgnn vpath_selector[queue_len - 1]; 2545221167Sgnn 2546221167Sgnn if (counter >= queue_len) 2547221167Sgnn counter = queue_len - 1; 2548221167Sgnn 2549221167Sgnn return (counter); 2550221167Sgnn} 2551221167Sgnn 2552221167Sgnnstatic inline vxge_hal_vpath_h 2553221167Sgnnvxge_vpath_handle_get(vxge_dev_t *vdev, int i) 2554221167Sgnn{ 2555221167Sgnn return (vdev->vpaths[i].is_open ? vdev->vpaths[i].handle : NULL); 2556221167Sgnn} 2557221167Sgnn 2558221167Sgnnint 2559221167Sgnnvxge_firmware_verify(vxge_dev_t *vdev) 2560221167Sgnn{ 2561221167Sgnn int err = 0; 2562221167Sgnn u64 active_config; 2563221167Sgnn vxge_hal_status_e status = VXGE_HAL_FAIL; 2564221167Sgnn 2565221167Sgnn if (vdev->fw_upgrade) { 2566221167Sgnn status = vxge_firmware_upgrade(vdev); 2567221167Sgnn if (status == VXGE_HAL_OK) { 2568221167Sgnn err = ENXIO; 2569221167Sgnn goto _exit0; 2570221167Sgnn } 2571221167Sgnn } 2572221167Sgnn 2573221167Sgnn if ((vdev->config.function_mode != VXGE_DEFAULT_CONFIG_VALUE) && 2574221167Sgnn (vdev->config.hw_info.function_mode != 2575221167Sgnn (u64) vdev->config.function_mode)) { 2576221167Sgnn 2577221167Sgnn status = vxge_func_mode_set(vdev); 2578221167Sgnn if (status == VXGE_HAL_OK) 2579221167Sgnn err = ENXIO; 2580221167Sgnn } 2581221167Sgnn 2582221167Sgnn /* l2_switch configuration */ 2583221167Sgnn active_config = VXGE_DEFAULT_CONFIG_VALUE; 2584221167Sgnn status = vxge_hal_get_active_config(vdev->devh, 2585221167Sgnn VXGE_HAL_XMAC_NWIF_ActConfig_L2SwitchEnabled, 2586221167Sgnn &active_config); 2587221167Sgnn 2588221167Sgnn if (status == VXGE_HAL_OK) { 2589221167Sgnn vdev->l2_switch = active_config; 2590221167Sgnn if (vdev->config.l2_switch != VXGE_DEFAULT_CONFIG_VALUE) { 2591221167Sgnn if (vdev->config.l2_switch != active_config) { 2592221167Sgnn status = vxge_l2switch_mode_set(vdev); 2593221167Sgnn if (status == VXGE_HAL_OK) 2594221167Sgnn err = ENXIO; 2595221167Sgnn } 2596221167Sgnn } 2597221167Sgnn } 2598221167Sgnn 2599221167Sgnn if (vdev->config.hw_info.ports == VXGE_DUAL_PORT_MODE) { 2600221167Sgnn if (vxge_port_mode_update(vdev) == ENXIO) 2601221167Sgnn err = ENXIO; 2602221167Sgnn } 2603221167Sgnn 2604221167Sgnn_exit0: 2605221167Sgnn if (err == ENXIO) 2606221167Sgnn device_printf(vdev->ndev, "PLEASE POWER CYCLE THE SYSTEM\n"); 2607221167Sgnn 2608221167Sgnn return (err); 2609221167Sgnn} 2610221167Sgnn 2611221167Sgnnvxge_hal_status_e 2612221167Sgnnvxge_firmware_upgrade(vxge_dev_t *vdev) 2613221167Sgnn{ 2614221167Sgnn u8 *fw_buffer; 2615221167Sgnn u32 fw_size; 2616221167Sgnn vxge_hal_device_hw_info_t *hw_info; 2617221167Sgnn vxge_hal_status_e status = VXGE_HAL_OK; 2618221167Sgnn 2619221167Sgnn hw_info = &vdev->config.hw_info; 2620221167Sgnn 2621221167Sgnn fw_size = sizeof(VXGE_FW_ARRAY_NAME); 2622221167Sgnn fw_buffer = (u8 *) VXGE_FW_ARRAY_NAME; 2623221167Sgnn 2624221167Sgnn device_printf(vdev->ndev, "Current firmware version : %s (%s)\n", 2625221167Sgnn hw_info->fw_version.version, hw_info->fw_date.date); 2626221167Sgnn 2627221167Sgnn device_printf(vdev->ndev, "Upgrading firmware to %d.%d.%d\n", 2628221167Sgnn VXGE_MIN_FW_MAJOR_VERSION, VXGE_MIN_FW_MINOR_VERSION, 2629221167Sgnn VXGE_MIN_FW_BUILD_NUMBER); 2630221167Sgnn 2631221167Sgnn /* Call HAL API to upgrade firmware */ 2632221167Sgnn status = vxge_hal_mrpcim_fw_upgrade(vdev->pdev, 2633221167Sgnn (pci_reg_h) vdev->pdev->reg_map[0], 2634221167Sgnn (u8 *) vdev->pdev->bar_info[0], 2635221167Sgnn fw_buffer, fw_size); 2636221167Sgnn 2637221167Sgnn device_printf(vdev->ndev, "firmware upgrade %s\n", 2638221167Sgnn (status == VXGE_HAL_OK) ? "successful" : "failed"); 2639221167Sgnn 2640221167Sgnn return (status); 2641221167Sgnn} 2642221167Sgnn 2643221167Sgnnvxge_hal_status_e 2644221167Sgnnvxge_func_mode_set(vxge_dev_t *vdev) 2645221167Sgnn{ 2646221167Sgnn u64 active_config; 2647221167Sgnn vxge_hal_status_e status = VXGE_HAL_FAIL; 2648221167Sgnn 2649221167Sgnn status = vxge_hal_mrpcim_pcie_func_mode_set(vdev->devh, 2650221167Sgnn vdev->config.function_mode); 2651221167Sgnn device_printf(vdev->ndev, 2652221167Sgnn "function mode change %s\n", 2653221167Sgnn (status == VXGE_HAL_OK) ? "successful" : "failed"); 2654221167Sgnn 2655221167Sgnn if (status == VXGE_HAL_OK) { 2656221167Sgnn vxge_hal_set_fw_api(vdev->devh, 0ULL, 2657221167Sgnn VXGE_HAL_API_FUNC_MODE_COMMIT, 2658221167Sgnn 0, 0ULL, 0ULL); 2659221167Sgnn 2660221167Sgnn vxge_hal_get_active_config(vdev->devh, 2661221167Sgnn VXGE_HAL_XMAC_NWIF_ActConfig_NWPortMode, 2662221167Sgnn &active_config); 2663221167Sgnn 2664221167Sgnn /* 2665221167Sgnn * If in MF + DP mode 2666221167Sgnn * if user changes to SF, change port_mode to single port mode 2667221167Sgnn */ 2668221167Sgnn if (((is_multi_func(vdev->config.hw_info.function_mode)) && 2669221167Sgnn is_single_func(vdev->config.function_mode)) && 2670221167Sgnn (active_config == VXGE_HAL_DP_NP_MODE_DUAL_PORT)) { 2671221167Sgnn vdev->config.port_mode = 2672221167Sgnn VXGE_HAL_DP_NP_MODE_SINGLE_PORT; 2673221167Sgnn 2674221167Sgnn status = vxge_port_mode_set(vdev); 2675221167Sgnn } 2676221167Sgnn } 2677221167Sgnn return (status); 2678221167Sgnn} 2679221167Sgnn 2680221167Sgnnvxge_hal_status_e 2681221167Sgnnvxge_port_mode_set(vxge_dev_t *vdev) 2682221167Sgnn{ 2683221167Sgnn vxge_hal_status_e status = VXGE_HAL_FAIL; 2684221167Sgnn 2685221167Sgnn status = vxge_hal_set_port_mode(vdev->devh, vdev->config.port_mode); 2686221167Sgnn device_printf(vdev->ndev, 2687221167Sgnn "port mode change %s\n", 2688221167Sgnn (status == VXGE_HAL_OK) ? "successful" : "failed"); 2689221167Sgnn 2690221167Sgnn if (status == VXGE_HAL_OK) { 2691221167Sgnn vxge_hal_set_fw_api(vdev->devh, 0ULL, 2692221167Sgnn VXGE_HAL_API_FUNC_MODE_COMMIT, 2693221167Sgnn 0, 0ULL, 0ULL); 2694221167Sgnn 2695221167Sgnn /* Configure vpath_mapping for active-active mode only */ 2696221167Sgnn if (vdev->config.port_mode == VXGE_HAL_DP_NP_MODE_DUAL_PORT) { 2697221167Sgnn 2698221167Sgnn status = vxge_hal_config_vpath_map(vdev->devh, 2699221167Sgnn VXGE_DUAL_PORT_MAP); 2700221167Sgnn 2701221167Sgnn device_printf(vdev->ndev, "dual port map change %s\n", 2702221167Sgnn (status == VXGE_HAL_OK) ? "successful" : "failed"); 2703221167Sgnn } 2704221167Sgnn } 2705221167Sgnn return (status); 2706221167Sgnn} 2707221167Sgnn 2708221167Sgnnint 2709221167Sgnnvxge_port_mode_update(vxge_dev_t *vdev) 2710221167Sgnn{ 2711221167Sgnn int err = 0; 2712221167Sgnn u64 active_config; 2713221167Sgnn vxge_hal_status_e status = VXGE_HAL_FAIL; 2714221167Sgnn 2715221167Sgnn if ((vdev->config.port_mode == VXGE_HAL_DP_NP_MODE_DUAL_PORT) && 2716221167Sgnn is_single_func(vdev->config.hw_info.function_mode)) { 2717221167Sgnn 2718221167Sgnn device_printf(vdev->ndev, 2719221167Sgnn "Adapter in SF mode, dual port mode is not allowed\n"); 2720221167Sgnn err = EPERM; 2721221167Sgnn goto _exit0; 2722221167Sgnn } 2723221167Sgnn 2724221167Sgnn active_config = VXGE_DEFAULT_CONFIG_VALUE; 2725221167Sgnn status = vxge_hal_get_active_config(vdev->devh, 2726221167Sgnn VXGE_HAL_XMAC_NWIF_ActConfig_NWPortMode, 2727221167Sgnn &active_config); 2728221167Sgnn if (status != VXGE_HAL_OK) { 2729221167Sgnn err = EINVAL; 2730221167Sgnn goto _exit0; 2731221167Sgnn } 2732221167Sgnn 2733221167Sgnn vdev->port_mode = active_config; 2734221167Sgnn if (vdev->config.port_mode != VXGE_DEFAULT_CONFIG_VALUE) { 2735221167Sgnn if (vdev->config.port_mode != vdev->port_mode) { 2736221167Sgnn status = vxge_port_mode_set(vdev); 2737221167Sgnn if (status != VXGE_HAL_OK) { 2738221167Sgnn err = EINVAL; 2739221167Sgnn goto _exit0; 2740221167Sgnn } 2741221167Sgnn err = ENXIO; 2742221167Sgnn vdev->port_mode = vdev->config.port_mode; 2743221167Sgnn } 2744221167Sgnn } 2745221167Sgnn 2746221167Sgnn active_config = VXGE_DEFAULT_CONFIG_VALUE; 2747221167Sgnn status = vxge_hal_get_active_config(vdev->devh, 2748221167Sgnn VXGE_HAL_XMAC_NWIF_ActConfig_BehaviourOnFail, 2749221167Sgnn &active_config); 2750221167Sgnn if (status != VXGE_HAL_OK) { 2751221167Sgnn err = EINVAL; 2752221167Sgnn goto _exit0; 2753221167Sgnn } 2754221167Sgnn 2755221167Sgnn vdev->port_failure = active_config; 2756221167Sgnn 2757221167Sgnn /* 2758221167Sgnn * active/active mode : set to NoMove 2759221167Sgnn * active/passive mode: set to Failover-Failback 2760221167Sgnn */ 2761221167Sgnn if (vdev->port_mode == VXGE_HAL_DP_NP_MODE_DUAL_PORT) 2762221167Sgnn vdev->config.port_failure = 2763221167Sgnn VXGE_HAL_XMAC_NWIF_OnFailure_NoMove; 2764221167Sgnn 2765221167Sgnn else if (vdev->port_mode == VXGE_HAL_DP_NP_MODE_ACTIVE_PASSIVE) 2766221167Sgnn vdev->config.port_failure = 2767221167Sgnn VXGE_HAL_XMAC_NWIF_OnFailure_OtherPortBackOnRestore; 2768221167Sgnn 2769221167Sgnn if ((vdev->port_mode != VXGE_HAL_DP_NP_MODE_SINGLE_PORT) && 2770221167Sgnn (vdev->config.port_failure != vdev->port_failure)) { 2771221167Sgnn status = vxge_port_behavior_on_failure_set(vdev); 2772221167Sgnn if (status == VXGE_HAL_OK) 2773221167Sgnn err = ENXIO; 2774221167Sgnn } 2775221167Sgnn 2776221167Sgnn_exit0: 2777221167Sgnn return (err); 2778221167Sgnn} 2779221167Sgnn 2780221167Sgnnvxge_hal_status_e 2781221167Sgnnvxge_port_mode_get(vxge_dev_t *vdev, vxge_port_info_t *port_info) 2782221167Sgnn{ 2783221167Sgnn int err = 0; 2784221167Sgnn u64 active_config; 2785221167Sgnn vxge_hal_status_e status = VXGE_HAL_FAIL; 2786221167Sgnn 2787221167Sgnn active_config = VXGE_DEFAULT_CONFIG_VALUE; 2788221167Sgnn status = vxge_hal_get_active_config(vdev->devh, 2789221167Sgnn VXGE_HAL_XMAC_NWIF_ActConfig_NWPortMode, 2790221167Sgnn &active_config); 2791221167Sgnn 2792221167Sgnn if (status != VXGE_HAL_OK) { 2793221167Sgnn err = ENXIO; 2794221167Sgnn goto _exit0; 2795221167Sgnn } 2796221167Sgnn 2797221167Sgnn port_info->port_mode = active_config; 2798221167Sgnn 2799221167Sgnn active_config = VXGE_DEFAULT_CONFIG_VALUE; 2800221167Sgnn status = vxge_hal_get_active_config(vdev->devh, 2801221167Sgnn VXGE_HAL_XMAC_NWIF_ActConfig_BehaviourOnFail, 2802221167Sgnn &active_config); 2803221167Sgnn if (status != VXGE_HAL_OK) { 2804221167Sgnn err = ENXIO; 2805221167Sgnn goto _exit0; 2806221167Sgnn } 2807221167Sgnn 2808221167Sgnn port_info->port_failure = active_config; 2809221167Sgnn 2810221167Sgnn_exit0: 2811221167Sgnn return (err); 2812221167Sgnn} 2813221167Sgnn 2814221167Sgnnvxge_hal_status_e 2815221167Sgnnvxge_port_behavior_on_failure_set(vxge_dev_t *vdev) 2816221167Sgnn{ 2817221167Sgnn vxge_hal_status_e status = VXGE_HAL_FAIL; 2818221167Sgnn 2819221167Sgnn status = vxge_hal_set_behavior_on_failure(vdev->devh, 2820221167Sgnn vdev->config.port_failure); 2821221167Sgnn 2822221167Sgnn device_printf(vdev->ndev, 2823221167Sgnn "port behaviour on failure change %s\n", 2824221167Sgnn (status == VXGE_HAL_OK) ? "successful" : "failed"); 2825221167Sgnn 2826221167Sgnn if (status == VXGE_HAL_OK) 2827221167Sgnn vxge_hal_set_fw_api(vdev->devh, 0ULL, 2828221167Sgnn VXGE_HAL_API_FUNC_MODE_COMMIT, 2829221167Sgnn 0, 0ULL, 0ULL); 2830221167Sgnn 2831221167Sgnn return (status); 2832221167Sgnn} 2833221167Sgnn 2834221167Sgnnvoid 2835221167Sgnnvxge_active_port_update(vxge_dev_t *vdev) 2836221167Sgnn{ 2837221167Sgnn u64 active_config; 2838221167Sgnn vxge_hal_status_e status = VXGE_HAL_FAIL; 2839221167Sgnn 2840221167Sgnn active_config = VXGE_DEFAULT_CONFIG_VALUE; 2841221167Sgnn status = vxge_hal_get_active_config(vdev->devh, 2842221167Sgnn VXGE_HAL_XMAC_NWIF_ActConfig_ActivePort, 2843221167Sgnn &active_config); 2844221167Sgnn 2845221167Sgnn if (status == VXGE_HAL_OK) 2846221167Sgnn vdev->active_port = active_config; 2847221167Sgnn} 2848221167Sgnn 2849221167Sgnnvxge_hal_status_e 2850221167Sgnnvxge_l2switch_mode_set(vxge_dev_t *vdev) 2851221167Sgnn{ 2852221167Sgnn vxge_hal_status_e status = VXGE_HAL_FAIL; 2853221167Sgnn 2854221167Sgnn status = vxge_hal_set_l2switch_mode(vdev->devh, 2855221167Sgnn vdev->config.l2_switch); 2856221167Sgnn 2857221167Sgnn device_printf(vdev->ndev, "L2 switch %s\n", 2858221167Sgnn (status == VXGE_HAL_OK) ? 2859221167Sgnn (vdev->config.l2_switch) ? "enable" : "disable" : 2860221167Sgnn "change failed"); 2861221167Sgnn 2862221167Sgnn if (status == VXGE_HAL_OK) 2863221167Sgnn vxge_hal_set_fw_api(vdev->devh, 0ULL, 2864221167Sgnn VXGE_HAL_API_FUNC_MODE_COMMIT, 2865221167Sgnn 0, 0ULL, 0ULL); 2866221167Sgnn 2867221167Sgnn return (status); 2868221167Sgnn} 2869221167Sgnn 2870221167Sgnn/* 2871221167Sgnn * vxge_promisc_set 2872221167Sgnn * Enable Promiscuous Mode 2873221167Sgnn */ 2874221167Sgnnvoid 2875221167Sgnnvxge_promisc_set(vxge_dev_t *vdev) 2876221167Sgnn{ 2877221167Sgnn int i; 2878221167Sgnn ifnet_t ifp; 2879221167Sgnn vxge_hal_vpath_h vpath_handle; 2880221167Sgnn 2881221167Sgnn if (!vdev->is_initialized) 2882221167Sgnn return; 2883221167Sgnn 2884221167Sgnn ifp = vdev->ifp; 2885221167Sgnn 2886221167Sgnn for (i = 0; i < vdev->no_of_vpath; i++) { 2887221167Sgnn vpath_handle = vxge_vpath_handle_get(vdev, i); 2888221167Sgnn if (!vpath_handle) 2889221167Sgnn continue; 2890221167Sgnn 2891221167Sgnn if (ifp->if_flags & IFF_PROMISC) 2892221167Sgnn vxge_hal_vpath_promisc_enable(vpath_handle); 2893221167Sgnn else 2894221167Sgnn vxge_hal_vpath_promisc_disable(vpath_handle); 2895221167Sgnn } 2896221167Sgnn} 2897221167Sgnn 2898221167Sgnn/* 2899221167Sgnn * vxge_change_mtu 2900221167Sgnn * Change interface MTU to a requested valid size 2901221167Sgnn */ 2902221167Sgnnint 2903221167Sgnnvxge_change_mtu(vxge_dev_t *vdev, unsigned long new_mtu) 2904221167Sgnn{ 2905221167Sgnn int err = EINVAL; 2906221167Sgnn 2907221167Sgnn if ((new_mtu < VXGE_HAL_MIN_MTU) || (new_mtu > VXGE_HAL_MAX_MTU)) 2908221167Sgnn goto _exit0; 2909221167Sgnn 2910221167Sgnn (vdev->ifp)->if_mtu = new_mtu; 2911221167Sgnn device_printf(vdev->ndev, "MTU changed to %ld\n", (vdev->ifp)->if_mtu); 2912221167Sgnn 2913221167Sgnn if (vdev->is_initialized) { 2914221167Sgnn if_down(vdev->ifp); 2915221167Sgnn vxge_reset(vdev); 2916221167Sgnn if_up(vdev->ifp); 2917221167Sgnn } 2918221167Sgnn err = 0; 2919221167Sgnn 2920221167Sgnn_exit0: 2921221167Sgnn return (err); 2922221167Sgnn} 2923221167Sgnn 2924221167Sgnn/* 2925221167Sgnn * Creates DMA tags for both Tx and Rx 2926221167Sgnn */ 2927221167Sgnnint 2928221167Sgnnvxge_dma_tags_create(vxge_vpath_t *vpath) 2929221167Sgnn{ 2930221167Sgnn int err = 0; 2931221167Sgnn bus_size_t max_size, boundary; 2932221167Sgnn vxge_dev_t *vdev = vpath->vdev; 2933221167Sgnn ifnet_t ifp = vdev->ifp; 2934221167Sgnn 2935221167Sgnn max_size = ifp->if_mtu + 2936221167Sgnn VXGE_HAL_MAC_HEADER_MAX_SIZE + 2937221167Sgnn VXGE_HAL_HEADER_ETHERNET_II_802_3_ALIGN; 2938221167Sgnn 2939221167Sgnn VXGE_BUFFER_ALIGN(max_size, 128) 2940221167Sgnn if (max_size <= MCLBYTES) 2941221167Sgnn vdev->rx_mbuf_sz = MCLBYTES; 2942221167Sgnn else 2943221167Sgnn vdev->rx_mbuf_sz = 2944221167Sgnn (max_size > MJUMPAGESIZE) ? MJUM9BYTES : MJUMPAGESIZE; 2945221167Sgnn 2946221167Sgnn boundary = (max_size > PAGE_SIZE) ? 0 : PAGE_SIZE; 2947221167Sgnn 2948221167Sgnn /* DMA tag for Tx */ 2949221167Sgnn err = bus_dma_tag_create( 2950221167Sgnn bus_get_dma_tag(vdev->ndev), 2951221167Sgnn 1, 2952221167Sgnn PAGE_SIZE, 2953221167Sgnn BUS_SPACE_MAXADDR, 2954221167Sgnn BUS_SPACE_MAXADDR, 2955221167Sgnn NULL, 2956221167Sgnn NULL, 2957221167Sgnn VXGE_TSO_SIZE, 2958221167Sgnn VXGE_MAX_SEGS, 2959221167Sgnn PAGE_SIZE, 2960221167Sgnn BUS_DMA_ALLOCNOW, 2961221167Sgnn NULL, 2962221167Sgnn NULL, 2963221167Sgnn &(vpath->dma_tag_tx)); 2964221167Sgnn if (err != 0) 2965221167Sgnn goto _exit0; 2966221167Sgnn 2967221167Sgnn /* DMA tag for Rx */ 2968221167Sgnn err = bus_dma_tag_create( 2969221167Sgnn bus_get_dma_tag(vdev->ndev), 2970221167Sgnn 1, 2971221167Sgnn boundary, 2972221167Sgnn BUS_SPACE_MAXADDR, 2973221167Sgnn BUS_SPACE_MAXADDR, 2974221167Sgnn NULL, 2975221167Sgnn NULL, 2976221167Sgnn vdev->rx_mbuf_sz, 2977221167Sgnn 1, 2978221167Sgnn vdev->rx_mbuf_sz, 2979221167Sgnn BUS_DMA_ALLOCNOW, 2980221167Sgnn NULL, 2981221167Sgnn NULL, 2982221167Sgnn &(vpath->dma_tag_rx)); 2983221167Sgnn if (err != 0) 2984221167Sgnn goto _exit1; 2985221167Sgnn 2986221167Sgnn /* Create DMA map for this descriptor */ 2987221167Sgnn err = bus_dmamap_create(vpath->dma_tag_rx, BUS_DMA_NOWAIT, 2988221167Sgnn &vpath->extra_dma_map); 2989221167Sgnn if (err == 0) 2990221167Sgnn goto _exit0; 2991221167Sgnn 2992221167Sgnn bus_dma_tag_destroy(vpath->dma_tag_rx); 2993221167Sgnn 2994221167Sgnn_exit1: 2995221167Sgnn bus_dma_tag_destroy(vpath->dma_tag_tx); 2996221167Sgnn 2997221167Sgnn_exit0: 2998221167Sgnn return (err); 2999221167Sgnn} 3000221167Sgnn 3001221167Sgnnstatic inline int 3002221167Sgnnvxge_dma_mbuf_coalesce(bus_dma_tag_t dma_tag_tx, bus_dmamap_t dma_map, 3003221167Sgnn mbuf_t * m_headp, bus_dma_segment_t * dma_buffers, 3004221167Sgnn int *num_segs) 3005221167Sgnn{ 3006221167Sgnn int err = 0; 3007221167Sgnn mbuf_t mbuf_pkt = NULL; 3008221167Sgnn 3009221167Sgnnretry: 3010221167Sgnn err = bus_dmamap_load_mbuf_sg(dma_tag_tx, dma_map, *m_headp, 3011221167Sgnn dma_buffers, num_segs, BUS_DMA_NOWAIT); 3012221167Sgnn if (err == EFBIG) { 3013221167Sgnn /* try to defrag, too many segments */ 3014243857Sglebius mbuf_pkt = m_defrag(*m_headp, M_NOWAIT); 3015221167Sgnn if (mbuf_pkt == NULL) { 3016221167Sgnn err = ENOBUFS; 3017221167Sgnn goto _exit0; 3018221167Sgnn } 3019221167Sgnn *m_headp = mbuf_pkt; 3020221167Sgnn goto retry; 3021221167Sgnn } 3022221167Sgnn 3023221167Sgnn_exit0: 3024221167Sgnn return (err); 3025221167Sgnn} 3026221167Sgnn 3027221167Sgnnint 3028221167Sgnnvxge_device_hw_info_get(vxge_dev_t *vdev) 3029221167Sgnn{ 3030221167Sgnn int i, err = ENXIO; 3031221167Sgnn u64 vpath_mask = 0; 3032221167Sgnn u32 max_supported_vpath = 0; 3033221167Sgnn u32 fw_ver_maj_min; 3034221167Sgnn vxge_firmware_upgrade_e fw_option; 3035221167Sgnn 3036221167Sgnn vxge_hal_status_e status = VXGE_HAL_OK; 3037221167Sgnn vxge_hal_device_hw_info_t *hw_info; 3038221167Sgnn 3039221167Sgnn status = vxge_hal_device_hw_info_get(vdev->pdev, 3040221167Sgnn (pci_reg_h) vdev->pdev->reg_map[0], 3041221167Sgnn (u8 *) vdev->pdev->bar_info[0], 3042221167Sgnn &vdev->config.hw_info); 3043221167Sgnn 3044221167Sgnn if (status != VXGE_HAL_OK) 3045221167Sgnn goto _exit0; 3046221167Sgnn 3047221167Sgnn hw_info = &vdev->config.hw_info; 3048221167Sgnn 3049221167Sgnn vpath_mask = hw_info->vpath_mask; 3050221167Sgnn if (vpath_mask == 0) { 3051221167Sgnn device_printf(vdev->ndev, "No vpaths available in device\n"); 3052221167Sgnn goto _exit0; 3053221167Sgnn } 3054221167Sgnn 3055221167Sgnn fw_option = vdev->config.fw_option; 3056221167Sgnn 3057221167Sgnn /* Check how many vpaths are available */ 3058221167Sgnn for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) { 3059221167Sgnn if (!((vpath_mask) & mBIT(i))) 3060221167Sgnn continue; 3061221167Sgnn max_supported_vpath++; 3062221167Sgnn } 3063221167Sgnn 3064221167Sgnn vdev->max_supported_vpath = max_supported_vpath; 3065221167Sgnn status = vxge_hal_device_is_privileged(hw_info->host_type, 3066221167Sgnn hw_info->func_id); 3067221167Sgnn vdev->is_privilaged = (status == VXGE_HAL_OK) ? TRUE : FALSE; 3068221167Sgnn 3069221167Sgnn vdev->hw_fw_version = VXGE_FW_VERSION( 3070221167Sgnn hw_info->fw_version.major, 3071221167Sgnn hw_info->fw_version.minor, 3072221167Sgnn hw_info->fw_version.build); 3073221167Sgnn 3074221167Sgnn fw_ver_maj_min = 3075221167Sgnn VXGE_FW_MAJ_MIN_VERSION(hw_info->fw_version.major, 3076221167Sgnn hw_info->fw_version.minor); 3077221167Sgnn 3078221167Sgnn if ((fw_option >= VXGE_FW_UPGRADE_FORCE) || 3079221167Sgnn (vdev->hw_fw_version != VXGE_DRV_FW_VERSION)) { 3080221167Sgnn 3081221167Sgnn /* For fw_ver 1.8.1 and above ignore build number. */ 3082221167Sgnn if ((fw_option == VXGE_FW_UPGRADE_ALL) && 3083221167Sgnn ((vdev->hw_fw_version >= VXGE_FW_VERSION(1, 8, 1)) && 3084221167Sgnn (fw_ver_maj_min == VXGE_DRV_FW_MAJ_MIN_VERSION))) { 3085221167Sgnn goto _exit1; 3086221167Sgnn } 3087221167Sgnn 3088221167Sgnn if (vdev->hw_fw_version < VXGE_BASE_FW_VERSION) { 3089221167Sgnn device_printf(vdev->ndev, 3090221167Sgnn "Upgrade driver through vxge_update, " 3091221167Sgnn "Unable to load the driver.\n"); 3092221167Sgnn goto _exit0; 3093221167Sgnn } 3094221167Sgnn vdev->fw_upgrade = TRUE; 3095221167Sgnn } 3096221167Sgnn 3097221167Sgnn_exit1: 3098221167Sgnn err = 0; 3099221167Sgnn 3100221167Sgnn_exit0: 3101221167Sgnn return (err); 3102221167Sgnn} 3103221167Sgnn 3104221167Sgnn/* 3105221167Sgnn * vxge_device_hw_info_print 3106221167Sgnn * Print device and driver information 3107221167Sgnn */ 3108221167Sgnnvoid 3109221167Sgnnvxge_device_hw_info_print(vxge_dev_t *vdev) 3110221167Sgnn{ 3111221167Sgnn u32 i; 3112221167Sgnn device_t ndev; 3113221167Sgnn struct sysctl_ctx_list *ctx; 3114221167Sgnn struct sysctl_oid_list *children; 3115221167Sgnn char pmd_type[2][VXGE_PMD_INFO_LEN]; 3116221167Sgnn 3117221167Sgnn vxge_hal_device_t *hldev; 3118221167Sgnn vxge_hal_device_hw_info_t *hw_info; 3119221167Sgnn vxge_hal_device_pmd_info_t *pmd_port; 3120221167Sgnn 3121221167Sgnn hldev = vdev->devh; 3122221167Sgnn ndev = vdev->ndev; 3123221167Sgnn 3124221167Sgnn ctx = device_get_sysctl_ctx(ndev); 3125221167Sgnn children = SYSCTL_CHILDREN(device_get_sysctl_tree(ndev)); 3126221167Sgnn 3127221167Sgnn hw_info = &(vdev->config.hw_info); 3128221167Sgnn 3129221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_DRV_VERSION], 3130221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_DRV_VERSION]), 3131221167Sgnn "%d.%d.%d.%d", XGELL_VERSION_MAJOR, XGELL_VERSION_MINOR, 3132221167Sgnn XGELL_VERSION_FIX, XGELL_VERSION_BUILD); 3133221167Sgnn 3134221167Sgnn /* Print PCI-e bus type/speed/width info */ 3135221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_PCIE_INFO], 3136221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_PCIE_INFO]), 3137221167Sgnn "x%d", hldev->link_width); 3138221167Sgnn 3139221167Sgnn if (hldev->link_width <= VXGE_HAL_PCI_E_LINK_WIDTH_X4) 3140221167Sgnn device_printf(ndev, "For optimal performance a x8 " 3141221167Sgnn "PCI-Express slot is required.\n"); 3142221167Sgnn 3143221167Sgnn vxge_null_terminate((char *) hw_info->serial_number, 3144221167Sgnn sizeof(hw_info->serial_number)); 3145221167Sgnn 3146221167Sgnn vxge_null_terminate((char *) hw_info->part_number, 3147221167Sgnn sizeof(hw_info->part_number)); 3148221167Sgnn 3149221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_SERIAL_NO], 3150221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_SERIAL_NO]), 3151221167Sgnn "%s", hw_info->serial_number); 3152221167Sgnn 3153221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_PART_NO], 3154221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_PART_NO]), 3155221167Sgnn "%s", hw_info->part_number); 3156221167Sgnn 3157221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_FW_VERSION], 3158221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_FW_VERSION]), 3159221167Sgnn "%s", hw_info->fw_version.version); 3160221167Sgnn 3161221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_FW_DATE], 3162221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_FW_DATE]), 3163221167Sgnn "%s", hw_info->fw_date.date); 3164221167Sgnn 3165221167Sgnn pmd_port = &(hw_info->pmd_port0); 3166221167Sgnn for (i = 0; i < hw_info->ports; i++) { 3167221167Sgnn 3168221167Sgnn vxge_pmd_port_type_get(vdev, pmd_port->type, 3169221167Sgnn pmd_type[i], sizeof(pmd_type[i])); 3170221167Sgnn 3171221167Sgnn strncpy(vdev->config.nic_attr[VXGE_PRINT_PMD_PORTS_0 + i], 3172221167Sgnn "vendor=??, sn=??, pn=??, type=??", 3173221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_PMD_PORTS_0 + i])); 3174221167Sgnn 3175221167Sgnn vxge_null_terminate(pmd_port->vendor, sizeof(pmd_port->vendor)); 3176221167Sgnn if (strlen(pmd_port->vendor) == 0) { 3177221167Sgnn pmd_port = &(hw_info->pmd_port1); 3178221167Sgnn continue; 3179221167Sgnn } 3180221167Sgnn 3181221167Sgnn vxge_null_terminate(pmd_port->ser_num, 3182221167Sgnn sizeof(pmd_port->ser_num)); 3183221167Sgnn 3184221167Sgnn vxge_null_terminate(pmd_port->part_num, 3185221167Sgnn sizeof(pmd_port->part_num)); 3186221167Sgnn 3187221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_PMD_PORTS_0 + i], 3188221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_PMD_PORTS_0 + i]), 3189221167Sgnn "vendor=%s, sn=%s, pn=%s, type=%s", 3190221167Sgnn pmd_port->vendor, pmd_port->ser_num, 3191221167Sgnn pmd_port->part_num, pmd_type[i]); 3192221167Sgnn 3193221167Sgnn pmd_port = &(hw_info->pmd_port1); 3194221167Sgnn } 3195221167Sgnn 3196221167Sgnn switch (hw_info->function_mode) { 3197221167Sgnn case VXGE_HAL_PCIE_FUNC_MODE_SF1_VP17: 3198221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_FUNC_MODE], 3199221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_FUNC_MODE]), 3200221167Sgnn "%s %d %s", "Single Function - 1 function(s)", 3201221167Sgnn vdev->max_supported_vpath, "VPath(s)/function"); 3202221167Sgnn break; 3203221167Sgnn 3204221167Sgnn case VXGE_HAL_PCIE_FUNC_MODE_MF2_VP8: 3205221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_FUNC_MODE], 3206221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_FUNC_MODE]), 3207221167Sgnn "%s %d %s", "Multi Function - 2 function(s)", 3208221167Sgnn vdev->max_supported_vpath, "VPath(s)/function"); 3209221167Sgnn break; 3210221167Sgnn 3211221167Sgnn case VXGE_HAL_PCIE_FUNC_MODE_MF4_VP4: 3212221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_FUNC_MODE], 3213221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_FUNC_MODE]), 3214221167Sgnn "%s %d %s", "Multi Function - 4 function(s)", 3215221167Sgnn vdev->max_supported_vpath, "VPath(s)/function"); 3216221167Sgnn break; 3217221167Sgnn 3218221167Sgnn case VXGE_HAL_PCIE_FUNC_MODE_MF8_VP2: 3219221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_FUNC_MODE], 3220221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_FUNC_MODE]), 3221221167Sgnn "%s %d %s", "Multi Function - 8 function(s)", 3222221167Sgnn vdev->max_supported_vpath, "VPath(s)/function"); 3223221167Sgnn break; 3224221167Sgnn 3225221167Sgnn case VXGE_HAL_PCIE_FUNC_MODE_MF8P_VP2: 3226221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_FUNC_MODE], 3227221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_FUNC_MODE]), 3228221167Sgnn "%s %d %s", "Multi Function (DirectIO) - 8 function(s)", 3229221167Sgnn vdev->max_supported_vpath, "VPath(s)/function"); 3230221167Sgnn break; 3231221167Sgnn } 3232221167Sgnn 3233221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_INTR_MODE], 3234221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_INTR_MODE]), 3235221167Sgnn "%s", ((vdev->config.intr_mode == VXGE_HAL_INTR_MODE_MSIX) ? 3236221167Sgnn "MSI-X" : "INTA")); 3237221167Sgnn 3238221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_VPATH_COUNT], 3239221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_VPATH_COUNT]), 3240221167Sgnn "%d", vdev->no_of_vpath); 3241221167Sgnn 3242221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_MTU_SIZE], 3243221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_MTU_SIZE]), 3244221167Sgnn "%lu", vdev->ifp->if_mtu); 3245221167Sgnn 3246221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_LRO_MODE], 3247221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_LRO_MODE]), 3248221167Sgnn "%s", ((vdev->config.lro_enable) ? "Enabled" : "Disabled")); 3249221167Sgnn 3250221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_RTH_MODE], 3251221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_RTH_MODE]), 3252221167Sgnn "%s", ((vdev->config.rth_enable) ? "Enabled" : "Disabled")); 3253221167Sgnn 3254221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_TSO_MODE], 3255221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_TSO_MODE]), 3256221167Sgnn "%s", ((vdev->ifp->if_capenable & IFCAP_TSO4) ? 3257221167Sgnn "Enabled" : "Disabled")); 3258221167Sgnn 3259221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_ADAPTER_TYPE], 3260221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_ADAPTER_TYPE]), 3261221167Sgnn "%s", ((hw_info->ports == 1) ? "Single Port" : "Dual Port")); 3262221167Sgnn 3263221167Sgnn if (vdev->is_privilaged) { 3264221167Sgnn 3265221167Sgnn if (hw_info->ports > 1) { 3266221167Sgnn 3267221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_PORT_MODE], 3268221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_PORT_MODE]), 3269221167Sgnn "%s", vxge_port_mode[vdev->port_mode]); 3270221167Sgnn 3271221167Sgnn if (vdev->port_mode != VXGE_HAL_DP_NP_MODE_SINGLE_PORT) 3272221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_PORT_FAILURE], 3273221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_PORT_FAILURE]), 3274221167Sgnn "%s", vxge_port_failure[vdev->port_failure]); 3275221167Sgnn 3276221167Sgnn vxge_active_port_update(vdev); 3277221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_ACTIVE_PORT], 3278221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_ACTIVE_PORT]), 3279221167Sgnn "%lld", vdev->active_port); 3280221167Sgnn } 3281221167Sgnn 3282221167Sgnn if (!is_single_func(hw_info->function_mode)) { 3283221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_L2SWITCH_MODE], 3284221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_L2SWITCH_MODE]), 3285221167Sgnn "%s", ((vdev->l2_switch) ? "Enabled" : "Disabled")); 3286221167Sgnn } 3287221167Sgnn } 3288221167Sgnn 3289221167Sgnn device_printf(ndev, "Driver version\t: %s\n", 3290221167Sgnn vdev->config.nic_attr[VXGE_PRINT_DRV_VERSION]); 3291221167Sgnn 3292221167Sgnn device_printf(ndev, "Serial number\t: %s\n", 3293221167Sgnn vdev->config.nic_attr[VXGE_PRINT_SERIAL_NO]); 3294221167Sgnn 3295221167Sgnn device_printf(ndev, "Part number\t: %s\n", 3296221167Sgnn vdev->config.nic_attr[VXGE_PRINT_PART_NO]); 3297221167Sgnn 3298221167Sgnn device_printf(ndev, "Firmware version\t: %s\n", 3299221167Sgnn vdev->config.nic_attr[VXGE_PRINT_FW_VERSION]); 3300221167Sgnn 3301221167Sgnn device_printf(ndev, "Firmware date\t: %s\n", 3302221167Sgnn vdev->config.nic_attr[VXGE_PRINT_FW_DATE]); 3303221167Sgnn 3304221167Sgnn device_printf(ndev, "Link width\t: %s\n", 3305221167Sgnn vdev->config.nic_attr[VXGE_PRINT_PCIE_INFO]); 3306221167Sgnn 3307221167Sgnn if (vdev->is_privilaged) { 3308221167Sgnn device_printf(ndev, "Function mode\t: %s\n", 3309221167Sgnn vdev->config.nic_attr[VXGE_PRINT_FUNC_MODE]); 3310221167Sgnn } 3311221167Sgnn 3312221167Sgnn device_printf(ndev, "Interrupt type\t: %s\n", 3313221167Sgnn vdev->config.nic_attr[VXGE_PRINT_INTR_MODE]); 3314221167Sgnn 3315221167Sgnn device_printf(ndev, "VPath(s) opened\t: %s\n", 3316221167Sgnn vdev->config.nic_attr[VXGE_PRINT_VPATH_COUNT]); 3317221167Sgnn 3318221167Sgnn device_printf(ndev, "Adapter Type\t: %s\n", 3319221167Sgnn vdev->config.nic_attr[VXGE_PRINT_ADAPTER_TYPE]); 3320221167Sgnn 3321221167Sgnn device_printf(ndev, "PMD Port 0\t: %s\n", 3322221167Sgnn vdev->config.nic_attr[VXGE_PRINT_PMD_PORTS_0]); 3323221167Sgnn 3324221167Sgnn if (hw_info->ports > 1) { 3325221167Sgnn device_printf(ndev, "PMD Port 1\t: %s\n", 3326221167Sgnn vdev->config.nic_attr[VXGE_PRINT_PMD_PORTS_1]); 3327221167Sgnn 3328221167Sgnn if (vdev->is_privilaged) { 3329221167Sgnn device_printf(ndev, "Port Mode\t: %s\n", 3330221167Sgnn vdev->config.nic_attr[VXGE_PRINT_PORT_MODE]); 3331221167Sgnn 3332221167Sgnn if (vdev->port_mode != VXGE_HAL_DP_NP_MODE_SINGLE_PORT) 3333221167Sgnn device_printf(ndev, "Port Failure\t: %s\n", 3334221167Sgnn vdev->config.nic_attr[VXGE_PRINT_PORT_FAILURE]); 3335221167Sgnn 3336221167Sgnn device_printf(vdev->ndev, "Active Port\t: %s\n", 3337221167Sgnn vdev->config.nic_attr[VXGE_PRINT_ACTIVE_PORT]); 3338221167Sgnn } 3339221167Sgnn } 3340221167Sgnn 3341221167Sgnn if (vdev->is_privilaged && !is_single_func(hw_info->function_mode)) { 3342221167Sgnn device_printf(vdev->ndev, "L2 Switch\t: %s\n", 3343221167Sgnn vdev->config.nic_attr[VXGE_PRINT_L2SWITCH_MODE]); 3344221167Sgnn } 3345221167Sgnn 3346221167Sgnn device_printf(ndev, "MTU is %s\n", 3347221167Sgnn vdev->config.nic_attr[VXGE_PRINT_MTU_SIZE]); 3348221167Sgnn 3349221167Sgnn device_printf(ndev, "LRO %s\n", 3350221167Sgnn vdev->config.nic_attr[VXGE_PRINT_LRO_MODE]); 3351221167Sgnn 3352221167Sgnn device_printf(ndev, "RTH %s\n", 3353221167Sgnn vdev->config.nic_attr[VXGE_PRINT_RTH_MODE]); 3354221167Sgnn 3355221167Sgnn device_printf(ndev, "TSO %s\n", 3356221167Sgnn vdev->config.nic_attr[VXGE_PRINT_TSO_MODE]); 3357221167Sgnn 3358221167Sgnn SYSCTL_ADD_STRING(ctx, children, 3359221167Sgnn OID_AUTO, "Driver version", CTLFLAG_RD, 3360273736Shselasky vdev->config.nic_attr[VXGE_PRINT_DRV_VERSION], 3361221167Sgnn 0, "Driver version"); 3362221167Sgnn 3363221167Sgnn SYSCTL_ADD_STRING(ctx, children, 3364221167Sgnn OID_AUTO, "Serial number", CTLFLAG_RD, 3365273736Shselasky vdev->config.nic_attr[VXGE_PRINT_SERIAL_NO], 3366221167Sgnn 0, "Serial number"); 3367221167Sgnn 3368221167Sgnn SYSCTL_ADD_STRING(ctx, children, 3369221167Sgnn OID_AUTO, "Part number", CTLFLAG_RD, 3370273736Shselasky vdev->config.nic_attr[VXGE_PRINT_PART_NO], 3371221167Sgnn 0, "Part number"); 3372221167Sgnn 3373221167Sgnn SYSCTL_ADD_STRING(ctx, children, 3374221167Sgnn OID_AUTO, "Firmware version", CTLFLAG_RD, 3375273736Shselasky vdev->config.nic_attr[VXGE_PRINT_FW_VERSION], 3376221167Sgnn 0, "Firmware version"); 3377221167Sgnn 3378221167Sgnn SYSCTL_ADD_STRING(ctx, children, 3379221167Sgnn OID_AUTO, "Firmware date", CTLFLAG_RD, 3380273736Shselasky vdev->config.nic_attr[VXGE_PRINT_FW_DATE], 3381221167Sgnn 0, "Firmware date"); 3382221167Sgnn 3383221167Sgnn SYSCTL_ADD_STRING(ctx, children, 3384221167Sgnn OID_AUTO, "Link width", CTLFLAG_RD, 3385273736Shselasky vdev->config.nic_attr[VXGE_PRINT_PCIE_INFO], 3386221167Sgnn 0, "Link width"); 3387221167Sgnn 3388221167Sgnn if (vdev->is_privilaged) { 3389221167Sgnn SYSCTL_ADD_STRING(ctx, children, 3390221167Sgnn OID_AUTO, "Function mode", CTLFLAG_RD, 3391273736Shselasky vdev->config.nic_attr[VXGE_PRINT_FUNC_MODE], 3392221167Sgnn 0, "Function mode"); 3393221167Sgnn } 3394221167Sgnn 3395221167Sgnn SYSCTL_ADD_STRING(ctx, children, 3396221167Sgnn OID_AUTO, "Interrupt type", CTLFLAG_RD, 3397273736Shselasky vdev->config.nic_attr[VXGE_PRINT_INTR_MODE], 3398221167Sgnn 0, "Interrupt type"); 3399221167Sgnn 3400221167Sgnn SYSCTL_ADD_STRING(ctx, children, 3401221167Sgnn OID_AUTO, "VPath(s) opened", CTLFLAG_RD, 3402273736Shselasky vdev->config.nic_attr[VXGE_PRINT_VPATH_COUNT], 3403221167Sgnn 0, "VPath(s) opened"); 3404221167Sgnn 3405221167Sgnn SYSCTL_ADD_STRING(ctx, children, 3406221167Sgnn OID_AUTO, "Adapter Type", CTLFLAG_RD, 3407273736Shselasky vdev->config.nic_attr[VXGE_PRINT_ADAPTER_TYPE], 3408221167Sgnn 0, "Adapter Type"); 3409221167Sgnn 3410221167Sgnn SYSCTL_ADD_STRING(ctx, children, 3411221167Sgnn OID_AUTO, "pmd port 0", CTLFLAG_RD, 3412273736Shselasky vdev->config.nic_attr[VXGE_PRINT_PMD_PORTS_0], 3413221167Sgnn 0, "pmd port"); 3414221167Sgnn 3415221167Sgnn if (hw_info->ports > 1) { 3416221167Sgnn 3417221167Sgnn SYSCTL_ADD_STRING(ctx, children, 3418221167Sgnn OID_AUTO, "pmd port 1", CTLFLAG_RD, 3419273736Shselasky vdev->config.nic_attr[VXGE_PRINT_PMD_PORTS_1], 3420221167Sgnn 0, "pmd port"); 3421221167Sgnn 3422221167Sgnn if (vdev->is_privilaged) { 3423221167Sgnn SYSCTL_ADD_STRING(ctx, children, 3424221167Sgnn OID_AUTO, "Port Mode", CTLFLAG_RD, 3425273736Shselasky vdev->config.nic_attr[VXGE_PRINT_PORT_MODE], 3426221167Sgnn 0, "Port Mode"); 3427221167Sgnn 3428221167Sgnn if (vdev->port_mode != VXGE_HAL_DP_NP_MODE_SINGLE_PORT) 3429221167Sgnn SYSCTL_ADD_STRING(ctx, children, 3430221167Sgnn OID_AUTO, "Port Failure", CTLFLAG_RD, 3431273736Shselasky vdev->config.nic_attr[VXGE_PRINT_PORT_FAILURE], 3432221167Sgnn 0, "Port Failure"); 3433221167Sgnn 3434221167Sgnn SYSCTL_ADD_STRING(ctx, children, 3435221167Sgnn OID_AUTO, "L2 Switch", CTLFLAG_RD, 3436273736Shselasky vdev->config.nic_attr[VXGE_PRINT_L2SWITCH_MODE], 3437221167Sgnn 0, "L2 Switch"); 3438221167Sgnn } 3439221167Sgnn } 3440221167Sgnn 3441221167Sgnn SYSCTL_ADD_STRING(ctx, children, 3442221167Sgnn OID_AUTO, "LRO mode", CTLFLAG_RD, 3443273736Shselasky vdev->config.nic_attr[VXGE_PRINT_LRO_MODE], 3444221167Sgnn 0, "LRO mode"); 3445221167Sgnn 3446221167Sgnn SYSCTL_ADD_STRING(ctx, children, 3447221167Sgnn OID_AUTO, "RTH mode", CTLFLAG_RD, 3448273736Shselasky vdev->config.nic_attr[VXGE_PRINT_RTH_MODE], 3449221167Sgnn 0, "RTH mode"); 3450221167Sgnn 3451221167Sgnn SYSCTL_ADD_STRING(ctx, children, 3452221167Sgnn OID_AUTO, "TSO mode", CTLFLAG_RD, 3453273736Shselasky vdev->config.nic_attr[VXGE_PRINT_TSO_MODE], 3454221167Sgnn 0, "TSO mode"); 3455221167Sgnn} 3456221167Sgnn 3457221167Sgnnvoid 3458221167Sgnnvxge_pmd_port_type_get(vxge_dev_t *vdev, u32 port_type, 3459221167Sgnn char *ifm_name, u8 ifm_len) 3460221167Sgnn{ 3461221167Sgnn 3462221167Sgnn vdev->ifm_optics = IFM_UNKNOWN; 3463221167Sgnn 3464221167Sgnn switch (port_type) { 3465221167Sgnn case VXGE_HAL_DEVICE_PMD_TYPE_10G_SR: 3466221167Sgnn vdev->ifm_optics = IFM_10G_SR; 3467221167Sgnn strlcpy(ifm_name, "10GbE SR", ifm_len); 3468221167Sgnn break; 3469221167Sgnn 3470221167Sgnn case VXGE_HAL_DEVICE_PMD_TYPE_10G_LR: 3471221167Sgnn vdev->ifm_optics = IFM_10G_LR; 3472221167Sgnn strlcpy(ifm_name, "10GbE LR", ifm_len); 3473221167Sgnn break; 3474221167Sgnn 3475221167Sgnn case VXGE_HAL_DEVICE_PMD_TYPE_10G_LRM: 3476221167Sgnn vdev->ifm_optics = IFM_10G_LRM; 3477221167Sgnn strlcpy(ifm_name, "10GbE LRM", ifm_len); 3478221167Sgnn break; 3479221167Sgnn 3480221167Sgnn case VXGE_HAL_DEVICE_PMD_TYPE_10G_DIRECT: 3481221167Sgnn vdev->ifm_optics = IFM_10G_TWINAX; 3482221167Sgnn strlcpy(ifm_name, "10GbE DA (Direct Attached)", ifm_len); 3483221167Sgnn break; 3484221167Sgnn 3485221167Sgnn case VXGE_HAL_DEVICE_PMD_TYPE_10G_CX4: 3486221167Sgnn vdev->ifm_optics = IFM_10G_CX4; 3487221167Sgnn strlcpy(ifm_name, "10GbE CX4", ifm_len); 3488221167Sgnn break; 3489221167Sgnn 3490221167Sgnn case VXGE_HAL_DEVICE_PMD_TYPE_10G_BASE_T: 3491221167Sgnn#if __FreeBSD_version >= 800000 3492221167Sgnn vdev->ifm_optics = IFM_10G_T; 3493221167Sgnn#endif 3494221167Sgnn strlcpy(ifm_name, "10GbE baseT", ifm_len); 3495221167Sgnn break; 3496221167Sgnn 3497221167Sgnn case VXGE_HAL_DEVICE_PMD_TYPE_10G_OTHER: 3498221167Sgnn strlcpy(ifm_name, "10GbE Other", ifm_len); 3499221167Sgnn break; 3500221167Sgnn 3501221167Sgnn case VXGE_HAL_DEVICE_PMD_TYPE_1G_SX: 3502221167Sgnn vdev->ifm_optics = IFM_1000_SX; 3503221167Sgnn strlcpy(ifm_name, "1GbE SX", ifm_len); 3504221167Sgnn break; 3505221167Sgnn 3506221167Sgnn case VXGE_HAL_DEVICE_PMD_TYPE_1G_LX: 3507221167Sgnn vdev->ifm_optics = IFM_1000_LX; 3508221167Sgnn strlcpy(ifm_name, "1GbE LX", ifm_len); 3509221167Sgnn break; 3510221167Sgnn 3511221167Sgnn case VXGE_HAL_DEVICE_PMD_TYPE_1G_CX: 3512221167Sgnn vdev->ifm_optics = IFM_1000_CX; 3513221167Sgnn strlcpy(ifm_name, "1GbE CX", ifm_len); 3514221167Sgnn break; 3515221167Sgnn 3516221167Sgnn case VXGE_HAL_DEVICE_PMD_TYPE_1G_BASE_T: 3517221167Sgnn vdev->ifm_optics = IFM_1000_T; 3518221167Sgnn strlcpy(ifm_name, "1GbE baseT", ifm_len); 3519221167Sgnn break; 3520221167Sgnn 3521221167Sgnn case VXGE_HAL_DEVICE_PMD_TYPE_1G_DIRECT: 3522221167Sgnn strlcpy(ifm_name, "1GbE DA (Direct Attached)", 3523221167Sgnn ifm_len); 3524221167Sgnn break; 3525221167Sgnn 3526221167Sgnn case VXGE_HAL_DEVICE_PMD_TYPE_1G_CX4: 3527221167Sgnn strlcpy(ifm_name, "1GbE CX4", ifm_len); 3528221167Sgnn break; 3529221167Sgnn 3530221167Sgnn case VXGE_HAL_DEVICE_PMD_TYPE_1G_OTHER: 3531221167Sgnn strlcpy(ifm_name, "1GbE Other", ifm_len); 3532221167Sgnn break; 3533221167Sgnn 3534221167Sgnn default: 3535221167Sgnn case VXGE_HAL_DEVICE_PMD_TYPE_UNKNOWN: 3536221167Sgnn strlcpy(ifm_name, "UNSUP", ifm_len); 3537221167Sgnn break; 3538221167Sgnn } 3539221167Sgnn} 3540221167Sgnn 3541221167Sgnnu32 3542221167Sgnnvxge_ring_length_get(u32 buffer_mode) 3543221167Sgnn{ 3544221167Sgnn return (VXGE_DEFAULT_RING_BLOCK * 3545221167Sgnn vxge_hal_ring_rxds_per_block_get(buffer_mode)); 3546221167Sgnn} 3547221167Sgnn 3548221167Sgnn/* 3549221167Sgnn * Removes trailing spaces padded 3550221167Sgnn * and NULL terminates strings 3551221167Sgnn */ 3552221167Sgnnstatic inline void 3553221167Sgnnvxge_null_terminate(char *str, size_t len) 3554221167Sgnn{ 3555221167Sgnn len--; 3556221167Sgnn while (*str && (*str != ' ') && (len != 0)) 3557221167Sgnn ++str; 3558221167Sgnn 3559221167Sgnn --len; 3560221167Sgnn if (*str) 3561221167Sgnn *str = '\0'; 3562221167Sgnn} 3563221167Sgnn 3564221167Sgnn/* 3565221167Sgnn * vxge_ioctl 3566221167Sgnn * Callback to control the device 3567221167Sgnn */ 3568221167Sgnnint 3569221167Sgnnvxge_ioctl(ifnet_t ifp, u_long command, caddr_t data) 3570221167Sgnn{ 3571221167Sgnn int mask, err = 0; 3572221167Sgnn vxge_dev_t *vdev = (vxge_dev_t *) ifp->if_softc; 3573221167Sgnn struct ifreq *ifr = (struct ifreq *) data; 3574221167Sgnn 3575221167Sgnn if (!vdev->is_active) 3576221167Sgnn return (EBUSY); 3577221167Sgnn 3578221167Sgnn switch (command) { 3579221167Sgnn /* Set/Get ifnet address */ 3580221167Sgnn case SIOCSIFADDR: 3581221167Sgnn case SIOCGIFADDR: 3582221167Sgnn ether_ioctl(ifp, command, data); 3583221167Sgnn break; 3584221167Sgnn 3585221167Sgnn /* Set Interface MTU */ 3586221167Sgnn case SIOCSIFMTU: 3587221167Sgnn err = vxge_change_mtu(vdev, (unsigned long)ifr->ifr_mtu); 3588221167Sgnn break; 3589221167Sgnn 3590221167Sgnn /* Set Interface Flags */ 3591221167Sgnn case SIOCSIFFLAGS: 3592221167Sgnn VXGE_DRV_LOCK(vdev); 3593221167Sgnn if (ifp->if_flags & IFF_UP) { 3594221167Sgnn if ((ifp->if_drv_flags & IFF_DRV_RUNNING)) { 3595221167Sgnn if ((ifp->if_flags ^ vdev->if_flags) & 3596221167Sgnn (IFF_PROMISC | IFF_ALLMULTI)) 3597221167Sgnn vxge_promisc_set(vdev); 3598221167Sgnn } else { 3599221167Sgnn vxge_init_locked(vdev); 3600221167Sgnn } 3601221167Sgnn } else { 3602221167Sgnn if (ifp->if_drv_flags & IFF_DRV_RUNNING) 3603221167Sgnn vxge_stop_locked(vdev); 3604221167Sgnn } 3605221167Sgnn vdev->if_flags = ifp->if_flags; 3606221167Sgnn VXGE_DRV_UNLOCK(vdev); 3607221167Sgnn break; 3608221167Sgnn 3609221167Sgnn /* Add/delete multicast address */ 3610221167Sgnn case SIOCADDMULTI: 3611221167Sgnn case SIOCDELMULTI: 3612221167Sgnn break; 3613221167Sgnn 3614221167Sgnn /* Get/Set Interface Media */ 3615221167Sgnn case SIOCSIFMEDIA: 3616221167Sgnn case SIOCGIFMEDIA: 3617221167Sgnn err = ifmedia_ioctl(ifp, ifr, &vdev->media, command); 3618221167Sgnn break; 3619221167Sgnn 3620221167Sgnn /* Set Capabilities */ 3621221167Sgnn case SIOCSIFCAP: 3622221167Sgnn VXGE_DRV_LOCK(vdev); 3623221167Sgnn mask = ifr->ifr_reqcap ^ ifp->if_capenable; 3624221167Sgnn 3625221167Sgnn if (mask & IFCAP_TXCSUM) { 3626221167Sgnn ifp->if_capenable ^= IFCAP_TXCSUM; 3627221167Sgnn ifp->if_hwassist ^= (CSUM_TCP | CSUM_UDP | CSUM_IP); 3628221167Sgnn 3629221167Sgnn if ((ifp->if_capenable & IFCAP_TSO) && 3630221167Sgnn !(ifp->if_capenable & IFCAP_TXCSUM)) { 3631221167Sgnn 3632221167Sgnn ifp->if_capenable &= ~IFCAP_TSO; 3633221167Sgnn ifp->if_hwassist &= ~CSUM_TSO; 3634221167Sgnn if_printf(ifp, "TSO Disabled\n"); 3635221167Sgnn } 3636221167Sgnn } 3637221167Sgnn if (mask & IFCAP_RXCSUM) 3638221167Sgnn ifp->if_capenable ^= IFCAP_RXCSUM; 3639221167Sgnn 3640221167Sgnn if (mask & IFCAP_TSO4) { 3641221167Sgnn ifp->if_capenable ^= IFCAP_TSO4; 3642221167Sgnn 3643221167Sgnn if (ifp->if_capenable & IFCAP_TSO) { 3644221167Sgnn if (ifp->if_capenable & IFCAP_TXCSUM) { 3645221167Sgnn ifp->if_hwassist |= CSUM_TSO; 3646221167Sgnn if_printf(ifp, "TSO Enabled\n"); 3647221167Sgnn } else { 3648221167Sgnn ifp->if_capenable &= ~IFCAP_TSO; 3649221167Sgnn ifp->if_hwassist &= ~CSUM_TSO; 3650221167Sgnn if_printf(ifp, 3651221167Sgnn "Enable tx checksum offload \ 3652221167Sgnn first.\n"); 3653221167Sgnn err = EAGAIN; 3654221167Sgnn } 3655221167Sgnn } else { 3656221167Sgnn ifp->if_hwassist &= ~CSUM_TSO; 3657221167Sgnn if_printf(ifp, "TSO Disabled\n"); 3658221167Sgnn } 3659221167Sgnn } 3660221167Sgnn if (mask & IFCAP_LRO) 3661221167Sgnn ifp->if_capenable ^= IFCAP_LRO; 3662221167Sgnn 3663221167Sgnn if (mask & IFCAP_VLAN_HWTAGGING) 3664221167Sgnn ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING; 3665221167Sgnn 3666221167Sgnn if (mask & IFCAP_VLAN_MTU) 3667221167Sgnn ifp->if_capenable ^= IFCAP_VLAN_MTU; 3668221167Sgnn 3669221167Sgnn if (mask & IFCAP_VLAN_HWCSUM) 3670221167Sgnn ifp->if_capenable ^= IFCAP_VLAN_HWCSUM; 3671221167Sgnn 3672221167Sgnn#if __FreeBSD_version >= 800000 3673221167Sgnn if (mask & IFCAP_VLAN_HWTSO) 3674221167Sgnn ifp->if_capenable ^= IFCAP_VLAN_HWTSO; 3675221167Sgnn#endif 3676221167Sgnn 3677221167Sgnn#if defined(VLAN_CAPABILITIES) 3678221167Sgnn VLAN_CAPABILITIES(ifp); 3679221167Sgnn#endif 3680221167Sgnn 3681221167Sgnn VXGE_DRV_UNLOCK(vdev); 3682221167Sgnn break; 3683221167Sgnn 3684221167Sgnn case SIOCGPRIVATE_0: 3685221167Sgnn VXGE_DRV_LOCK(vdev); 3686221167Sgnn err = vxge_ioctl_stats(vdev, ifr); 3687221167Sgnn VXGE_DRV_UNLOCK(vdev); 3688221167Sgnn break; 3689221167Sgnn 3690221167Sgnn case SIOCGPRIVATE_1: 3691221167Sgnn VXGE_DRV_LOCK(vdev); 3692221167Sgnn err = vxge_ioctl_regs(vdev, ifr); 3693221167Sgnn VXGE_DRV_UNLOCK(vdev); 3694221167Sgnn break; 3695221167Sgnn 3696221167Sgnn default: 3697221167Sgnn err = ether_ioctl(ifp, command, data); 3698221167Sgnn break; 3699221167Sgnn } 3700221167Sgnn 3701221167Sgnn return (err); 3702221167Sgnn} 3703221167Sgnn 3704221167Sgnn/* 3705221167Sgnn * vxge_ioctl_regs 3706221167Sgnn * IOCTL to get registers 3707221167Sgnn */ 3708221167Sgnnint 3709221167Sgnnvxge_ioctl_regs(vxge_dev_t *vdev, struct ifreq *ifr) 3710221167Sgnn{ 3711221167Sgnn u64 value = 0x0; 3712221167Sgnn u32 vp_id = 0; 3713221167Sgnn u32 offset, reqd_size = 0; 3714221167Sgnn int i, err = EINVAL; 3715221167Sgnn 3716221167Sgnn char *command = (char *) ifr->ifr_data; 3717221167Sgnn void *reg_info = (void *) ifr->ifr_data; 3718221167Sgnn 3719221167Sgnn vxge_vpath_t *vpath; 3720221167Sgnn vxge_hal_status_e status = VXGE_HAL_OK; 3721221167Sgnn vxge_hal_mgmt_reg_type_e regs_type; 3722221167Sgnn 3723221167Sgnn switch (*command) { 3724221167Sgnn case vxge_hal_mgmt_reg_type_pcicfgmgmt: 3725221167Sgnn if (vdev->is_privilaged) { 3726221167Sgnn reqd_size = sizeof(vxge_hal_pcicfgmgmt_reg_t); 3727221167Sgnn regs_type = vxge_hal_mgmt_reg_type_pcicfgmgmt; 3728221167Sgnn } 3729221167Sgnn break; 3730221167Sgnn 3731221167Sgnn case vxge_hal_mgmt_reg_type_mrpcim: 3732221167Sgnn if (vdev->is_privilaged) { 3733221167Sgnn reqd_size = sizeof(vxge_hal_mrpcim_reg_t); 3734221167Sgnn regs_type = vxge_hal_mgmt_reg_type_mrpcim; 3735221167Sgnn } 3736221167Sgnn break; 3737221167Sgnn 3738221167Sgnn case vxge_hal_mgmt_reg_type_srpcim: 3739221167Sgnn if (vdev->is_privilaged) { 3740221167Sgnn reqd_size = sizeof(vxge_hal_srpcim_reg_t); 3741221167Sgnn regs_type = vxge_hal_mgmt_reg_type_srpcim; 3742221167Sgnn } 3743221167Sgnn break; 3744221167Sgnn 3745221167Sgnn case vxge_hal_mgmt_reg_type_memrepair: 3746221167Sgnn if (vdev->is_privilaged) { 3747221167Sgnn /* reqd_size = sizeof(vxge_hal_memrepair_reg_t); */ 3748221167Sgnn regs_type = vxge_hal_mgmt_reg_type_memrepair; 3749221167Sgnn } 3750221167Sgnn break; 3751221167Sgnn 3752221167Sgnn case vxge_hal_mgmt_reg_type_legacy: 3753221167Sgnn reqd_size = sizeof(vxge_hal_legacy_reg_t); 3754221167Sgnn regs_type = vxge_hal_mgmt_reg_type_legacy; 3755221167Sgnn break; 3756221167Sgnn 3757221167Sgnn case vxge_hal_mgmt_reg_type_toc: 3758221167Sgnn reqd_size = sizeof(vxge_hal_toc_reg_t); 3759221167Sgnn regs_type = vxge_hal_mgmt_reg_type_toc; 3760221167Sgnn break; 3761221167Sgnn 3762221167Sgnn case vxge_hal_mgmt_reg_type_common: 3763221167Sgnn reqd_size = sizeof(vxge_hal_common_reg_t); 3764221167Sgnn regs_type = vxge_hal_mgmt_reg_type_common; 3765221167Sgnn break; 3766221167Sgnn 3767221167Sgnn case vxge_hal_mgmt_reg_type_vpmgmt: 3768221167Sgnn reqd_size = sizeof(vxge_hal_vpmgmt_reg_t); 3769221167Sgnn regs_type = vxge_hal_mgmt_reg_type_vpmgmt; 3770221167Sgnn vpath = &(vdev->vpaths[*((u32 *) reg_info + 1)]); 3771221167Sgnn vp_id = vpath->vp_id; 3772221167Sgnn break; 3773221167Sgnn 3774221167Sgnn case vxge_hal_mgmt_reg_type_vpath: 3775221167Sgnn reqd_size = sizeof(vxge_hal_vpath_reg_t); 3776221167Sgnn regs_type = vxge_hal_mgmt_reg_type_vpath; 3777221167Sgnn vpath = &(vdev->vpaths[*((u32 *) reg_info + 1)]); 3778221167Sgnn vp_id = vpath->vp_id; 3779221167Sgnn break; 3780221167Sgnn 3781221167Sgnn case VXGE_GET_VPATH_COUNT: 3782221167Sgnn *((u32 *) reg_info) = vdev->no_of_vpath; 3783221167Sgnn err = 0; 3784221167Sgnn break; 3785221167Sgnn 3786221167Sgnn default: 3787221167Sgnn reqd_size = 0; 3788221167Sgnn break; 3789221167Sgnn } 3790221167Sgnn 3791221167Sgnn if (reqd_size) { 3792221167Sgnn for (i = 0, offset = 0; offset < reqd_size; 3793221167Sgnn i++, offset += 0x0008) { 3794221167Sgnn value = 0x0; 3795221167Sgnn status = vxge_hal_mgmt_reg_read(vdev->devh, regs_type, 3796221167Sgnn vp_id, offset, &value); 3797221167Sgnn 3798221167Sgnn err = (status != VXGE_HAL_OK) ? EINVAL : 0; 3799221167Sgnn if (err == EINVAL) 3800221167Sgnn break; 3801221167Sgnn 3802221167Sgnn *((u64 *) ((u64 *) reg_info + i)) = value; 3803221167Sgnn } 3804221167Sgnn } 3805221167Sgnn return (err); 3806221167Sgnn} 3807221167Sgnn 3808221167Sgnn/* 3809221167Sgnn * vxge_ioctl_stats 3810221167Sgnn * IOCTL to get statistics 3811221167Sgnn */ 3812221167Sgnnint 3813221167Sgnnvxge_ioctl_stats(vxge_dev_t *vdev, struct ifreq *ifr) 3814221167Sgnn{ 3815221167Sgnn int i, retsize, err = EINVAL; 3816221167Sgnn u32 bufsize; 3817221167Sgnn 3818221167Sgnn vxge_vpath_t *vpath; 3819221167Sgnn vxge_bw_info_t *bw_info; 3820221167Sgnn vxge_port_info_t *port_info; 3821221167Sgnn vxge_drv_stats_t *drv_stat; 3822221167Sgnn 3823221167Sgnn char *buffer = NULL; 3824221167Sgnn char *command = (char *) ifr->ifr_data; 3825221167Sgnn vxge_hal_status_e status = VXGE_HAL_OK; 3826221167Sgnn 3827221167Sgnn switch (*command) { 3828221167Sgnn case VXGE_GET_PCI_CONF: 3829221167Sgnn bufsize = VXGE_STATS_BUFFER_SIZE; 3830221167Sgnn buffer = (char *) vxge_mem_alloc(bufsize); 3831221167Sgnn if (buffer != NULL) { 3832221167Sgnn status = vxge_hal_aux_pci_config_read(vdev->devh, 3833221167Sgnn bufsize, buffer, &retsize); 3834221167Sgnn if (status == VXGE_HAL_OK) 3835221167Sgnn err = copyout(buffer, ifr->ifr_data, retsize); 3836221167Sgnn else 3837221167Sgnn device_printf(vdev->ndev, 3838221167Sgnn "failed pciconfig statistics query\n"); 3839221167Sgnn 3840221167Sgnn vxge_mem_free(buffer, bufsize); 3841221167Sgnn } 3842221167Sgnn break; 3843221167Sgnn 3844221167Sgnn case VXGE_GET_MRPCIM_STATS: 3845221167Sgnn if (!vdev->is_privilaged) 3846221167Sgnn break; 3847221167Sgnn 3848221167Sgnn bufsize = VXGE_STATS_BUFFER_SIZE; 3849221167Sgnn buffer = (char *) vxge_mem_alloc(bufsize); 3850221167Sgnn if (buffer != NULL) { 3851221167Sgnn status = vxge_hal_aux_stats_mrpcim_read(vdev->devh, 3852221167Sgnn bufsize, buffer, &retsize); 3853221167Sgnn if (status == VXGE_HAL_OK) 3854221167Sgnn err = copyout(buffer, ifr->ifr_data, retsize); 3855221167Sgnn else 3856221167Sgnn device_printf(vdev->ndev, 3857221167Sgnn "failed mrpcim statistics query\n"); 3858221167Sgnn 3859221167Sgnn vxge_mem_free(buffer, bufsize); 3860221167Sgnn } 3861221167Sgnn break; 3862221167Sgnn 3863221167Sgnn case VXGE_GET_DEVICE_STATS: 3864221167Sgnn bufsize = VXGE_STATS_BUFFER_SIZE; 3865221167Sgnn buffer = (char *) vxge_mem_alloc(bufsize); 3866221167Sgnn if (buffer != NULL) { 3867221167Sgnn status = vxge_hal_aux_stats_device_read(vdev->devh, 3868221167Sgnn bufsize, buffer, &retsize); 3869221167Sgnn if (status == VXGE_HAL_OK) 3870221167Sgnn err = copyout(buffer, ifr->ifr_data, retsize); 3871221167Sgnn else 3872221167Sgnn device_printf(vdev->ndev, 3873221167Sgnn "failed device statistics query\n"); 3874221167Sgnn 3875221167Sgnn vxge_mem_free(buffer, bufsize); 3876221167Sgnn } 3877221167Sgnn break; 3878221167Sgnn 3879221167Sgnn case VXGE_GET_DEVICE_HWINFO: 3880221167Sgnn bufsize = sizeof(vxge_device_hw_info_t); 3881221167Sgnn buffer = (char *) vxge_mem_alloc(bufsize); 3882221167Sgnn if (buffer != NULL) { 3883221167Sgnn vxge_os_memcpy( 3884221167Sgnn &(((vxge_device_hw_info_t *) buffer)->hw_info), 3885221167Sgnn &vdev->config.hw_info, 3886221167Sgnn sizeof(vxge_hal_device_hw_info_t)); 3887221167Sgnn 3888221167Sgnn ((vxge_device_hw_info_t *) buffer)->port_mode = 3889221167Sgnn vdev->port_mode; 3890221167Sgnn 3891221167Sgnn ((vxge_device_hw_info_t *) buffer)->port_failure = 3892221167Sgnn vdev->port_failure; 3893221167Sgnn 3894221167Sgnn err = copyout(buffer, ifr->ifr_data, bufsize); 3895221167Sgnn if (err != 0) 3896221167Sgnn device_printf(vdev->ndev, 3897221167Sgnn "failed device hardware info query\n"); 3898221167Sgnn 3899221167Sgnn vxge_mem_free(buffer, bufsize); 3900221167Sgnn } 3901221167Sgnn break; 3902221167Sgnn 3903221167Sgnn case VXGE_GET_DRIVER_STATS: 3904221167Sgnn bufsize = sizeof(vxge_drv_stats_t) * vdev->no_of_vpath; 3905221167Sgnn drv_stat = (vxge_drv_stats_t *) vxge_mem_alloc(bufsize); 3906221167Sgnn if (drv_stat != NULL) { 3907221167Sgnn for (i = 0; i < vdev->no_of_vpath; i++) { 3908221167Sgnn vpath = &(vdev->vpaths[i]); 3909221167Sgnn 3910221167Sgnn vpath->driver_stats.rx_lro_queued += 3911221167Sgnn vpath->lro.lro_queued; 3912221167Sgnn 3913221167Sgnn vpath->driver_stats.rx_lro_flushed += 3914221167Sgnn vpath->lro.lro_flushed; 3915221167Sgnn 3916221167Sgnn vxge_os_memcpy(&drv_stat[i], 3917221167Sgnn &(vpath->driver_stats), 3918221167Sgnn sizeof(vxge_drv_stats_t)); 3919221167Sgnn } 3920221167Sgnn 3921221167Sgnn err = copyout(drv_stat, ifr->ifr_data, bufsize); 3922221167Sgnn if (err != 0) 3923221167Sgnn device_printf(vdev->ndev, 3924221167Sgnn "failed driver statistics query\n"); 3925221167Sgnn 3926221167Sgnn vxge_mem_free(drv_stat, bufsize); 3927221167Sgnn } 3928221167Sgnn break; 3929221167Sgnn 3930221167Sgnn case VXGE_GET_BANDWIDTH: 3931221167Sgnn bw_info = (vxge_bw_info_t *) ifr->ifr_data; 3932221167Sgnn 3933221167Sgnn if ((vdev->config.hw_info.func_id != 0) && 3934221167Sgnn (vdev->hw_fw_version < VXGE_FW_VERSION(1, 8, 0))) 3935221167Sgnn break; 3936221167Sgnn 3937221167Sgnn if (vdev->config.hw_info.func_id != 0) 3938221167Sgnn bw_info->func_id = vdev->config.hw_info.func_id; 3939221167Sgnn 3940221167Sgnn status = vxge_bw_priority_get(vdev, bw_info); 3941221167Sgnn if (status != VXGE_HAL_OK) 3942221167Sgnn break; 3943221167Sgnn 3944221167Sgnn err = copyout(bw_info, ifr->ifr_data, sizeof(vxge_bw_info_t)); 3945221167Sgnn break; 3946221167Sgnn 3947221167Sgnn case VXGE_SET_BANDWIDTH: 3948221167Sgnn if (vdev->is_privilaged) 3949221167Sgnn err = vxge_bw_priority_set(vdev, ifr); 3950221167Sgnn break; 3951221167Sgnn 3952221167Sgnn case VXGE_SET_PORT_MODE: 3953221167Sgnn if (vdev->is_privilaged) { 3954221167Sgnn if (vdev->config.hw_info.ports == VXGE_DUAL_PORT_MODE) { 3955221167Sgnn port_info = (vxge_port_info_t *) ifr->ifr_data; 3956221167Sgnn vdev->config.port_mode = port_info->port_mode; 3957221167Sgnn err = vxge_port_mode_update(vdev); 3958221167Sgnn if (err != ENXIO) 3959221167Sgnn err = VXGE_HAL_FAIL; 3960221167Sgnn else { 3961221167Sgnn err = VXGE_HAL_OK; 3962221167Sgnn device_printf(vdev->ndev, 3963221167Sgnn "PLEASE POWER CYCLE THE SYSTEM\n"); 3964221167Sgnn } 3965221167Sgnn } 3966221167Sgnn } 3967221167Sgnn break; 3968221167Sgnn 3969221167Sgnn case VXGE_GET_PORT_MODE: 3970221167Sgnn if (vdev->is_privilaged) { 3971221167Sgnn if (vdev->config.hw_info.ports == VXGE_DUAL_PORT_MODE) { 3972221167Sgnn port_info = (vxge_port_info_t *) ifr->ifr_data; 3973221167Sgnn err = vxge_port_mode_get(vdev, port_info); 3974221167Sgnn if (err == VXGE_HAL_OK) { 3975221167Sgnn err = copyout(port_info, ifr->ifr_data, 3976221167Sgnn sizeof(vxge_port_info_t)); 3977221167Sgnn } 3978221167Sgnn } 3979221167Sgnn } 3980221167Sgnn break; 3981221167Sgnn 3982221167Sgnn default: 3983221167Sgnn break; 3984221167Sgnn } 3985221167Sgnn 3986221167Sgnn return (err); 3987221167Sgnn} 3988221167Sgnn 3989221167Sgnnint 3990221167Sgnnvxge_bw_priority_config(vxge_dev_t *vdev) 3991221167Sgnn{ 3992221167Sgnn u32 i; 3993221167Sgnn int err = EINVAL; 3994221167Sgnn 3995221167Sgnn for (i = 0; i < vdev->no_of_func; i++) { 3996221167Sgnn err = vxge_bw_priority_update(vdev, i, TRUE); 3997221167Sgnn if (err != 0) 3998221167Sgnn break; 3999221167Sgnn } 4000221167Sgnn 4001221167Sgnn return (err); 4002221167Sgnn} 4003221167Sgnn 4004221167Sgnnint 4005221167Sgnnvxge_bw_priority_set(vxge_dev_t *vdev, struct ifreq *ifr) 4006221167Sgnn{ 4007221167Sgnn int err; 4008221167Sgnn u32 func_id; 4009221167Sgnn vxge_bw_info_t *bw_info; 4010221167Sgnn 4011221167Sgnn bw_info = (vxge_bw_info_t *) ifr->ifr_data; 4012221167Sgnn func_id = bw_info->func_id; 4013221167Sgnn 4014221167Sgnn vdev->config.bw_info[func_id].priority = bw_info->priority; 4015221167Sgnn vdev->config.bw_info[func_id].bandwidth = bw_info->bandwidth; 4016221167Sgnn 4017221167Sgnn err = vxge_bw_priority_update(vdev, func_id, FALSE); 4018221167Sgnn 4019221167Sgnn return (err); 4020221167Sgnn} 4021221167Sgnn 4022221167Sgnnint 4023221167Sgnnvxge_bw_priority_update(vxge_dev_t *vdev, u32 func_id, bool binit) 4024221167Sgnn{ 4025221167Sgnn u32 i, set = 0; 4026221167Sgnn u32 bandwidth, priority, vpath_count; 4027221167Sgnn u64 vpath_list[VXGE_HAL_MAX_VIRTUAL_PATHS]; 4028221167Sgnn 4029221167Sgnn vxge_hal_device_t *hldev; 4030221167Sgnn vxge_hal_vp_config_t *vp_config; 4031221167Sgnn vxge_hal_status_e status = VXGE_HAL_OK; 4032221167Sgnn 4033221167Sgnn hldev = vdev->devh; 4034221167Sgnn 4035221167Sgnn status = vxge_hal_get_vpath_list(vdev->devh, func_id, 4036221167Sgnn vpath_list, &vpath_count); 4037221167Sgnn 4038221167Sgnn if (status != VXGE_HAL_OK) 4039221167Sgnn return (status); 4040221167Sgnn 4041221167Sgnn for (i = 0; i < vpath_count; i++) { 4042221167Sgnn vp_config = &(hldev->config.vp_config[vpath_list[i]]); 4043221167Sgnn 4044221167Sgnn /* Configure Bandwidth */ 4045221167Sgnn if (vdev->config.bw_info[func_id].bandwidth != 4046221167Sgnn VXGE_HAL_VPATH_BW_LIMIT_DEFAULT) { 4047221167Sgnn 4048221167Sgnn set = 1; 4049221167Sgnn bandwidth = vdev->config.bw_info[func_id].bandwidth; 4050221167Sgnn if (bandwidth < VXGE_HAL_VPATH_BW_LIMIT_MIN || 4051221167Sgnn bandwidth > VXGE_HAL_VPATH_BW_LIMIT_MAX) { 4052221167Sgnn 4053221167Sgnn bandwidth = VXGE_HAL_VPATH_BW_LIMIT_DEFAULT; 4054221167Sgnn } 4055221167Sgnn vp_config->bandwidth = bandwidth; 4056221167Sgnn } 4057221167Sgnn 4058221167Sgnn /* 4059221167Sgnn * If b/w limiting is enabled on any of the 4060221167Sgnn * VFs, then for remaining VFs set the priority to 3 4061221167Sgnn * and b/w limiting to max i.e 10 Gb) 4062221167Sgnn */ 4063221167Sgnn if (vp_config->bandwidth == VXGE_HAL_VPATH_BW_LIMIT_DEFAULT) 4064221167Sgnn vp_config->bandwidth = VXGE_HAL_VPATH_BW_LIMIT_MAX; 4065221167Sgnn 4066221167Sgnn if (binit && vdev->config.low_latency) { 4067221167Sgnn if (func_id == 0) 4068221167Sgnn vdev->config.bw_info[func_id].priority = 4069221167Sgnn VXGE_DEFAULT_VPATH_PRIORITY_HIGH; 4070221167Sgnn } 4071221167Sgnn 4072221167Sgnn /* Configure Priority */ 4073221167Sgnn if (vdev->config.bw_info[func_id].priority != 4074221167Sgnn VXGE_HAL_VPATH_PRIORITY_DEFAULT) { 4075221167Sgnn 4076221167Sgnn set = 1; 4077221167Sgnn priority = vdev->config.bw_info[func_id].priority; 4078221167Sgnn if (priority < VXGE_HAL_VPATH_PRIORITY_MIN || 4079221167Sgnn priority > VXGE_HAL_VPATH_PRIORITY_MAX) { 4080221167Sgnn 4081221167Sgnn priority = VXGE_HAL_VPATH_PRIORITY_DEFAULT; 4082221167Sgnn } 4083221167Sgnn vp_config->priority = priority; 4084221167Sgnn 4085221167Sgnn } else if (vdev->config.low_latency) { 4086221167Sgnn set = 1; 4087221167Sgnn vp_config->priority = VXGE_DEFAULT_VPATH_PRIORITY_LOW; 4088221167Sgnn } 4089221167Sgnn 4090221167Sgnn if (set == 1) { 4091221167Sgnn status = vxge_hal_rx_bw_priority_set(vdev->devh, 4092221167Sgnn vpath_list[i]); 4093221167Sgnn if (status != VXGE_HAL_OK) 4094221167Sgnn break; 4095221167Sgnn 4096221167Sgnn if (vpath_list[i] < VXGE_HAL_TX_BW_VPATH_LIMIT) { 4097221167Sgnn status = vxge_hal_tx_bw_priority_set( 4098221167Sgnn vdev->devh, vpath_list[i]); 4099221167Sgnn if (status != VXGE_HAL_OK) 4100221167Sgnn break; 4101221167Sgnn } 4102221167Sgnn } 4103221167Sgnn } 4104221167Sgnn 4105221167Sgnn return ((status == VXGE_HAL_OK) ? 0 : EINVAL); 4106221167Sgnn} 4107221167Sgnn 4108221167Sgnn/* 4109221167Sgnn * vxge_intr_coalesce_tx 4110221167Sgnn * Changes interrupt coalescing if the interrupts are not within a range 4111221167Sgnn * Return Value: Nothing 4112221167Sgnn */ 4113221167Sgnnvoid 4114221167Sgnnvxge_intr_coalesce_tx(vxge_vpath_t *vpath) 4115221167Sgnn{ 4116221167Sgnn u32 timer; 4117221167Sgnn 4118221167Sgnn if (!vpath->tx_intr_coalesce) 4119221167Sgnn return; 4120221167Sgnn 4121221167Sgnn vpath->tx_interrupts++; 4122221167Sgnn if (ticks > vpath->tx_ticks + hz/100) { 4123221167Sgnn 4124221167Sgnn vpath->tx_ticks = ticks; 4125221167Sgnn timer = vpath->tti_rtimer_val; 4126221167Sgnn if (vpath->tx_interrupts > VXGE_MAX_TX_INTERRUPT_COUNT) { 4127221167Sgnn if (timer != VXGE_TTI_RTIMER_ADAPT_VAL) { 4128221167Sgnn vpath->tti_rtimer_val = 4129221167Sgnn VXGE_TTI_RTIMER_ADAPT_VAL; 4130221167Sgnn 4131221167Sgnn vxge_hal_vpath_dynamic_tti_rtimer_set( 4132221167Sgnn vpath->handle, vpath->tti_rtimer_val); 4133221167Sgnn } 4134221167Sgnn } else { 4135221167Sgnn if (timer != 0) { 4136221167Sgnn vpath->tti_rtimer_val = 0; 4137221167Sgnn vxge_hal_vpath_dynamic_tti_rtimer_set( 4138221167Sgnn vpath->handle, vpath->tti_rtimer_val); 4139221167Sgnn } 4140221167Sgnn } 4141221167Sgnn vpath->tx_interrupts = 0; 4142221167Sgnn } 4143221167Sgnn} 4144221167Sgnn 4145221167Sgnn/* 4146221167Sgnn * vxge_intr_coalesce_rx 4147221167Sgnn * Changes interrupt coalescing if the interrupts are not within a range 4148221167Sgnn * Return Value: Nothing 4149221167Sgnn */ 4150221167Sgnnvoid 4151221167Sgnnvxge_intr_coalesce_rx(vxge_vpath_t *vpath) 4152221167Sgnn{ 4153221167Sgnn u32 timer; 4154221167Sgnn 4155221167Sgnn if (!vpath->rx_intr_coalesce) 4156221167Sgnn return; 4157221167Sgnn 4158221167Sgnn vpath->rx_interrupts++; 4159221167Sgnn if (ticks > vpath->rx_ticks + hz/100) { 4160221167Sgnn 4161221167Sgnn vpath->rx_ticks = ticks; 4162221167Sgnn timer = vpath->rti_rtimer_val; 4163221167Sgnn 4164221167Sgnn if (vpath->rx_interrupts > VXGE_MAX_RX_INTERRUPT_COUNT) { 4165221167Sgnn if (timer != VXGE_RTI_RTIMER_ADAPT_VAL) { 4166221167Sgnn vpath->rti_rtimer_val = 4167221167Sgnn VXGE_RTI_RTIMER_ADAPT_VAL; 4168221167Sgnn 4169221167Sgnn vxge_hal_vpath_dynamic_rti_rtimer_set( 4170221167Sgnn vpath->handle, vpath->rti_rtimer_val); 4171221167Sgnn } 4172221167Sgnn } else { 4173221167Sgnn if (timer != 0) { 4174221167Sgnn vpath->rti_rtimer_val = 0; 4175221167Sgnn vxge_hal_vpath_dynamic_rti_rtimer_set( 4176221167Sgnn vpath->handle, vpath->rti_rtimer_val); 4177221167Sgnn } 4178221167Sgnn } 4179221167Sgnn vpath->rx_interrupts = 0; 4180221167Sgnn } 4181221167Sgnn} 4182221167Sgnn 4183221167Sgnn/* 4184221167Sgnn * vxge_methods FreeBSD device interface entry points 4185221167Sgnn */ 4186221167Sgnnstatic device_method_t vxge_methods[] = { 4187221167Sgnn DEVMETHOD(device_probe, vxge_probe), 4188221167Sgnn DEVMETHOD(device_attach, vxge_attach), 4189221167Sgnn DEVMETHOD(device_detach, vxge_detach), 4190221167Sgnn DEVMETHOD(device_shutdown, vxge_shutdown), 4191246128Ssbz 4192246128Ssbz DEVMETHOD_END 4193221167Sgnn}; 4194221167Sgnn 4195221167Sgnnstatic driver_t vxge_driver = { 4196221167Sgnn "vxge", vxge_methods, sizeof(vxge_dev_t), 4197221167Sgnn}; 4198221167Sgnn 4199221167Sgnnstatic devclass_t vxge_devclass; 4200221167Sgnn 4201221167SgnnDRIVER_MODULE(vxge, pci, vxge_driver, vxge_devclass, 0, 0); 4202