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$*/ 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); 663221167Sgnn } else if ((m_head->m_flags & M_FLOWID) != 0) { 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 } 712243440Sglebius ifp->if_obytes += next->m_pkthdr.len; 713243440Sglebius if (next->m_flags & M_MCAST) 714243440Sglebius 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 1073221167Sgnn mbuf_up->m_flags |= M_FLOWID; 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 1195248078Smarius 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_mtu = ETHERMTU; 1384221167Sgnn ifp->if_baudrate = VXGE_BAUDRATE; 1385221167Sgnn ifp->if_init = vxge_init; 1386221167Sgnn ifp->if_softc = vdev; 1387221167Sgnn ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 1388221167Sgnn ifp->if_ioctl = vxge_ioctl; 1389221167Sgnn ifp->if_start = vxge_send; 1390221167Sgnn 1391221167Sgnn#if __FreeBSD_version >= 800000 1392221167Sgnn ifp->if_transmit = vxge_mq_send; 1393221167Sgnn ifp->if_qflush = vxge_mq_qflush; 1394221167Sgnn#endif 1395221167Sgnn ifp->if_snd.ifq_drv_maxlen = max(vdev->config.ifq_maxlen, ifqmaxlen); 1396221167Sgnn IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen); 1397221167Sgnn /* IFQ_SET_READY(&ifp->if_snd); */ 1398221167Sgnn 1399221167Sgnn ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header); 1400221167Sgnn 1401221167Sgnn ifp->if_capabilities |= IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM; 1402221167Sgnn ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU; 1403221167Sgnn ifp->if_capabilities |= IFCAP_JUMBO_MTU; 1404221167Sgnn 1405221167Sgnn if (vdev->config.tso_enable) 1406221167Sgnn vxge_tso_config(vdev); 1407221167Sgnn 1408221167Sgnn if (vdev->config.lro_enable) 1409221167Sgnn ifp->if_capabilities |= IFCAP_LRO; 1410221167Sgnn 1411221167Sgnn ifp->if_capenable = ifp->if_capabilities; 1412221167Sgnn 1413221167Sgnn strlcpy(vdev->ndev_name, device_get_nameunit(ndev), 1414221167Sgnn sizeof(vdev->ndev_name)); 1415221167Sgnn 1416221167Sgnn /* Attach the interface */ 1417221167Sgnn ether_ifattach(ifp, vdev->vpaths[0].mac_addr); 1418221167Sgnn 1419221167Sgnn_exit0: 1420221167Sgnn return (err); 1421221167Sgnn} 1422221167Sgnn 1423221167Sgnn/* 1424221167Sgnn * vxge_isr_setup 1425221167Sgnn * Register isr functions 1426221167Sgnn */ 1427221167Sgnnint 1428221167Sgnnvxge_isr_setup(vxge_dev_t *vdev) 1429221167Sgnn{ 1430221167Sgnn int i, irq_rid, err = 0; 1431221167Sgnn vxge_vpath_t *vpath; 1432221167Sgnn 1433221167Sgnn void *isr_func_arg; 1434221167Sgnn void (*isr_func_ptr) (void *); 1435221167Sgnn 1436221167Sgnn switch (vdev->config.intr_mode) { 1437221167Sgnn case VXGE_HAL_INTR_MODE_IRQLINE: 1438221167Sgnn err = bus_setup_intr(vdev->ndev, 1439221167Sgnn vdev->config.isr_info[0].irq_res, 1440221167Sgnn (INTR_TYPE_NET | INTR_MPSAFE), 1441221167Sgnn vxge_isr_filter, vxge_isr_line, vdev, 1442221167Sgnn &vdev->config.isr_info[0].irq_handle); 1443221167Sgnn break; 1444221167Sgnn 1445221167Sgnn case VXGE_HAL_INTR_MODE_MSIX: 1446221167Sgnn for (i = 0; i < vdev->intr_count; i++) { 1447221167Sgnn 1448221167Sgnn irq_rid = vdev->config.isr_info[i].irq_rid; 1449221167Sgnn vpath = &vdev->vpaths[irq_rid / 4]; 1450221167Sgnn 1451221167Sgnn if ((irq_rid % 4) == 2) { 1452221167Sgnn isr_func_ptr = vxge_isr_msix; 1453221167Sgnn isr_func_arg = (void *) vpath; 1454221167Sgnn } else if ((irq_rid % 4) == 3) { 1455221167Sgnn isr_func_ptr = vxge_isr_msix_alarm; 1456221167Sgnn isr_func_arg = (void *) vpath; 1457221167Sgnn } else 1458221167Sgnn break; 1459221167Sgnn 1460221167Sgnn err = bus_setup_intr(vdev->ndev, 1461221167Sgnn vdev->config.isr_info[i].irq_res, 1462221167Sgnn (INTR_TYPE_NET | INTR_MPSAFE), NULL, 1463221167Sgnn (void *) isr_func_ptr, (void *) isr_func_arg, 1464221167Sgnn &vdev->config.isr_info[i].irq_handle); 1465221167Sgnn if (err != 0) 1466221167Sgnn break; 1467221167Sgnn } 1468221167Sgnn 1469221167Sgnn if (err != 0) { 1470221167Sgnn /* Teardown interrupt handler */ 1471221167Sgnn while (--i > 0) 1472221167Sgnn bus_teardown_intr(vdev->ndev, 1473221167Sgnn vdev->config.isr_info[i].irq_res, 1474221167Sgnn vdev->config.isr_info[i].irq_handle); 1475221167Sgnn } 1476221167Sgnn break; 1477221167Sgnn } 1478221167Sgnn 1479221167Sgnn return (err); 1480221167Sgnn} 1481221167Sgnn 1482221167Sgnn/* 1483221167Sgnn * vxge_isr_filter 1484221167Sgnn * ISR filter function - filter interrupts from other shared devices 1485221167Sgnn */ 1486221167Sgnnint 1487221167Sgnnvxge_isr_filter(void *handle) 1488221167Sgnn{ 1489221167Sgnn u64 val64 = 0; 1490221167Sgnn vxge_dev_t *vdev = (vxge_dev_t *) handle; 1491221167Sgnn __hal_device_t *hldev = (__hal_device_t *) vdev->devh; 1492221167Sgnn 1493221167Sgnn vxge_hal_common_reg_t *common_reg = 1494221167Sgnn (vxge_hal_common_reg_t *) (hldev->common_reg); 1495221167Sgnn 1496221167Sgnn val64 = vxge_os_pio_mem_read64(vdev->pdev, (vdev->devh)->regh0, 1497221167Sgnn &common_reg->titan_general_int_status); 1498221167Sgnn 1499221167Sgnn return ((val64) ? FILTER_SCHEDULE_THREAD : FILTER_STRAY); 1500221167Sgnn} 1501221167Sgnn 1502221167Sgnn/* 1503221167Sgnn * vxge_isr_line 1504221167Sgnn * Interrupt service routine for Line interrupts 1505221167Sgnn */ 1506221167Sgnnvoid 1507221167Sgnnvxge_isr_line(void *vdev_ptr) 1508221167Sgnn{ 1509221167Sgnn vxge_dev_t *vdev = (vxge_dev_t *) vdev_ptr; 1510221167Sgnn 1511221167Sgnn vxge_hal_device_handle_irq(vdev->devh, 0); 1512221167Sgnn} 1513221167Sgnn 1514221167Sgnnvoid 1515221167Sgnnvxge_isr_msix(void *vpath_ptr) 1516221167Sgnn{ 1517221167Sgnn u32 got_rx = 0; 1518221167Sgnn u32 got_tx = 0; 1519221167Sgnn 1520221167Sgnn __hal_virtualpath_t *hal_vpath; 1521221167Sgnn vxge_vpath_t *vpath = (vxge_vpath_t *) vpath_ptr; 1522221167Sgnn vxge_dev_t *vdev = vpath->vdev; 1523221167Sgnn hal_vpath = ((__hal_vpath_handle_t *) vpath->handle)->vpath; 1524221167Sgnn 1525221167Sgnn VXGE_DRV_STATS(vpath, isr_msix); 1526221167Sgnn VXGE_HAL_DEVICE_STATS_SW_INFO_TRAFFIC_INTR(vdev->devh); 1527221167Sgnn 1528221167Sgnn vxge_hal_vpath_mf_msix_mask(vpath->handle, vpath->msix_vec); 1529221167Sgnn 1530221167Sgnn /* processing rx */ 1531221167Sgnn vxge_hal_vpath_poll_rx(vpath->handle, &got_rx); 1532221167Sgnn 1533221167Sgnn /* processing tx */ 1534221167Sgnn if (hal_vpath->vp_config->fifo.enable) { 1535221167Sgnn vxge_intr_coalesce_tx(vpath); 1536221167Sgnn vxge_hal_vpath_poll_tx(vpath->handle, &got_tx); 1537221167Sgnn } 1538221167Sgnn 1539221167Sgnn vxge_hal_vpath_mf_msix_unmask(vpath->handle, vpath->msix_vec); 1540221167Sgnn} 1541221167Sgnn 1542221167Sgnnvoid 1543221167Sgnnvxge_isr_msix_alarm(void *vpath_ptr) 1544221167Sgnn{ 1545221167Sgnn int i; 1546221167Sgnn vxge_hal_status_e status = VXGE_HAL_OK; 1547221167Sgnn 1548221167Sgnn vxge_vpath_t *vpath = (vxge_vpath_t *) vpath_ptr; 1549221167Sgnn vxge_dev_t *vdev = vpath->vdev; 1550221167Sgnn 1551221167Sgnn VXGE_HAL_DEVICE_STATS_SW_INFO_NOT_TRAFFIC_INTR(vdev->devh); 1552221167Sgnn 1553221167Sgnn /* Process alarms in each vpath */ 1554221167Sgnn for (i = 0; i < vdev->no_of_vpath; i++) { 1555221167Sgnn 1556221167Sgnn vpath = &(vdev->vpaths[i]); 1557221167Sgnn vxge_hal_vpath_mf_msix_mask(vpath->handle, 1558221167Sgnn vpath->msix_vec_alarm); 1559221167Sgnn status = vxge_hal_vpath_alarm_process(vpath->handle, 0); 1560221167Sgnn if ((status == VXGE_HAL_ERR_EVENT_SLOT_FREEZE) || 1561221167Sgnn (status == VXGE_HAL_ERR_EVENT_SERR)) { 1562221167Sgnn device_printf(vdev->ndev, 1563221167Sgnn "processing alarms urecoverable error %x\n", 1564221167Sgnn status); 1565221167Sgnn 1566221167Sgnn /* Stop the driver */ 1567221167Sgnn vdev->is_initialized = FALSE; 1568221167Sgnn break; 1569221167Sgnn } 1570221167Sgnn vxge_hal_vpath_mf_msix_unmask(vpath->handle, 1571221167Sgnn vpath->msix_vec_alarm); 1572221167Sgnn } 1573221167Sgnn} 1574221167Sgnn 1575221167Sgnn/* 1576221167Sgnn * vxge_msix_enable 1577221167Sgnn */ 1578221167Sgnnvxge_hal_status_e 1579221167Sgnnvxge_msix_enable(vxge_dev_t *vdev) 1580221167Sgnn{ 1581221167Sgnn int i, first_vp_id, msix_id; 1582221167Sgnn 1583221167Sgnn vxge_vpath_t *vpath; 1584221167Sgnn vxge_hal_status_e status = VXGE_HAL_OK; 1585221167Sgnn 1586221167Sgnn /* 1587221167Sgnn * Unmasking and Setting MSIX vectors before enabling interrupts 1588221167Sgnn * tim[] : 0 - Tx ## 1 - Rx ## 2 - UMQ-DMQ ## 0 - BITMAP 1589221167Sgnn */ 1590221167Sgnn int tim[4] = {0, 1, 0, 0}; 1591221167Sgnn 1592221167Sgnn for (i = 0; i < vdev->no_of_vpath; i++) { 1593221167Sgnn 1594221167Sgnn vpath = vdev->vpaths + i; 1595221167Sgnn first_vp_id = vdev->vpaths[0].vp_id; 1596221167Sgnn 1597221167Sgnn msix_id = vpath->vp_id * VXGE_HAL_VPATH_MSIX_ACTIVE; 1598221167Sgnn tim[1] = vpath->msix_vec = msix_id + 1; 1599221167Sgnn 1600221167Sgnn vpath->msix_vec_alarm = first_vp_id * 1601221167Sgnn VXGE_HAL_VPATH_MSIX_ACTIVE + VXGE_HAL_VPATH_MSIX_ALARM_ID; 1602221167Sgnn 1603221167Sgnn status = vxge_hal_vpath_mf_msix_set(vpath->handle, 1604221167Sgnn tim, VXGE_HAL_VPATH_MSIX_ALARM_ID); 1605221167Sgnn 1606221167Sgnn if (status != VXGE_HAL_OK) { 1607221167Sgnn device_printf(vdev->ndev, 1608221167Sgnn "failed to set msix vectors to vpath\n"); 1609221167Sgnn break; 1610221167Sgnn } 1611221167Sgnn 1612221167Sgnn vxge_hal_vpath_mf_msix_unmask(vpath->handle, vpath->msix_vec); 1613221167Sgnn vxge_hal_vpath_mf_msix_unmask(vpath->handle, 1614221167Sgnn vpath->msix_vec_alarm); 1615221167Sgnn } 1616221167Sgnn 1617221167Sgnn return (status); 1618221167Sgnn} 1619221167Sgnn 1620221167Sgnn/* 1621221167Sgnn * vxge_media_init 1622221167Sgnn * Initializes, adds and sets media 1623221167Sgnn */ 1624221167Sgnnvoid 1625221167Sgnnvxge_media_init(vxge_dev_t *vdev) 1626221167Sgnn{ 1627221167Sgnn ifmedia_init(&vdev->media, 1628221167Sgnn IFM_IMASK, vxge_media_change, vxge_media_status); 1629221167Sgnn 1630221167Sgnn /* Add supported media */ 1631221167Sgnn ifmedia_add(&vdev->media, 1632221167Sgnn IFM_ETHER | vdev->ifm_optics | IFM_FDX, 1633221167Sgnn 0, NULL); 1634221167Sgnn 1635221167Sgnn /* Set media */ 1636221167Sgnn ifmedia_add(&vdev->media, IFM_ETHER | IFM_AUTO, 0, NULL); 1637221167Sgnn ifmedia_set(&vdev->media, IFM_ETHER | IFM_AUTO); 1638221167Sgnn} 1639221167Sgnn 1640221167Sgnn/* 1641221167Sgnn * vxge_media_status 1642221167Sgnn * Callback for interface media settings 1643221167Sgnn */ 1644221167Sgnnvoid 1645221167Sgnnvxge_media_status(ifnet_t ifp, struct ifmediareq *ifmr) 1646221167Sgnn{ 1647221167Sgnn vxge_dev_t *vdev = (vxge_dev_t *) ifp->if_softc; 1648221167Sgnn vxge_hal_device_t *hldev = vdev->devh; 1649221167Sgnn 1650221167Sgnn ifmr->ifm_status = IFM_AVALID; 1651221167Sgnn ifmr->ifm_active = IFM_ETHER; 1652221167Sgnn 1653221167Sgnn /* set link state */ 1654221167Sgnn if (vxge_hal_device_link_state_get(hldev) == VXGE_HAL_LINK_UP) { 1655221167Sgnn ifmr->ifm_status |= IFM_ACTIVE; 1656221167Sgnn ifmr->ifm_active |= vdev->ifm_optics | IFM_FDX; 1657221167Sgnn if_link_state_change(ifp, LINK_STATE_UP); 1658221167Sgnn } 1659221167Sgnn} 1660221167Sgnn 1661221167Sgnn/* 1662221167Sgnn * vxge_media_change 1663221167Sgnn * Media change driver callback 1664221167Sgnn */ 1665221167Sgnnint 1666221167Sgnnvxge_media_change(ifnet_t ifp) 1667221167Sgnn{ 1668221167Sgnn vxge_dev_t *vdev = (vxge_dev_t *) ifp->if_softc; 1669221167Sgnn struct ifmedia *ifmediap = &vdev->media; 1670221167Sgnn 1671221167Sgnn return (IFM_TYPE(ifmediap->ifm_media) != IFM_ETHER ? EINVAL : 0); 1672221167Sgnn} 1673221167Sgnn 1674221167Sgnn/* 1675221167Sgnn * Allocate PCI resources 1676221167Sgnn */ 1677221167Sgnnint 1678221167Sgnnvxge_alloc_resources(vxge_dev_t *vdev) 1679221167Sgnn{ 1680221167Sgnn int err = 0; 1681221167Sgnn vxge_pci_info_t *pci_info = NULL; 1682221167Sgnn vxge_free_resources_e error_level = VXGE_FREE_NONE; 1683221167Sgnn 1684221167Sgnn device_t ndev = vdev->ndev; 1685221167Sgnn 1686221167Sgnn /* Allocate Buffer for HAL Device Configuration */ 1687221167Sgnn vdev->device_config = (vxge_hal_device_config_t *) 1688221167Sgnn vxge_mem_alloc(sizeof(vxge_hal_device_config_t)); 1689221167Sgnn 1690221167Sgnn if (!vdev->device_config) { 1691221167Sgnn err = ENOMEM; 1692221167Sgnn error_level = VXGE_DISABLE_PCI_BUSMASTER; 1693221167Sgnn device_printf(vdev->ndev, 1694221167Sgnn "failed to allocate memory for device config\n"); 1695221167Sgnn goto _exit0; 1696221167Sgnn } 1697221167Sgnn 1698221167Sgnn 1699221167Sgnn pci_info = (vxge_pci_info_t *) vxge_mem_alloc(sizeof(vxge_pci_info_t)); 1700221167Sgnn if (!pci_info) { 1701221167Sgnn error_level = VXGE_FREE_DEVICE_CONFIG; 1702221167Sgnn err = ENOMEM; 1703221167Sgnn device_printf(vdev->ndev, 1704221167Sgnn "failed to allocate memory for pci info\n"); 1705221167Sgnn goto _exit0; 1706221167Sgnn } 1707221167Sgnn pci_info->ndev = ndev; 1708221167Sgnn vdev->pdev = pci_info; 1709221167Sgnn 1710221167Sgnn err = vxge_alloc_bar_resources(vdev, 0); 1711221167Sgnn if (err != 0) { 1712221167Sgnn error_level = VXGE_FREE_BAR0; 1713221167Sgnn goto _exit0; 1714221167Sgnn } 1715221167Sgnn 1716221167Sgnn err = vxge_alloc_bar_resources(vdev, 1); 1717221167Sgnn if (err != 0) { 1718221167Sgnn error_level = VXGE_FREE_BAR1; 1719221167Sgnn goto _exit0; 1720221167Sgnn } 1721221167Sgnn 1722221167Sgnn err = vxge_alloc_bar_resources(vdev, 2); 1723221167Sgnn if (err != 0) 1724221167Sgnn error_level = VXGE_FREE_BAR2; 1725221167Sgnn 1726221167Sgnn_exit0: 1727221167Sgnn if (error_level) 1728221167Sgnn vxge_free_resources(ndev, error_level); 1729221167Sgnn 1730221167Sgnn return (err); 1731221167Sgnn} 1732221167Sgnn 1733221167Sgnn/* 1734221167Sgnn * vxge_alloc_bar_resources 1735221167Sgnn * Allocates BAR resources 1736221167Sgnn */ 1737221167Sgnnint 1738221167Sgnnvxge_alloc_bar_resources(vxge_dev_t *vdev, int i) 1739221167Sgnn{ 1740221167Sgnn int err = 0; 1741221167Sgnn int res_id = 0; 1742221167Sgnn vxge_pci_info_t *pci_info = vdev->pdev; 1743221167Sgnn 1744221167Sgnn res_id = PCIR_BAR((i == 0) ? 0 : (i * 2)); 1745221167Sgnn 1746221167Sgnn pci_info->bar_info[i] = 1747221167Sgnn bus_alloc_resource_any(vdev->ndev, 1748221167Sgnn SYS_RES_MEMORY, &res_id, RF_ACTIVE); 1749221167Sgnn 1750221167Sgnn if (pci_info->bar_info[i] == NULL) { 1751221167Sgnn device_printf(vdev->ndev, 1752221167Sgnn "failed to allocate memory for bus resources\n"); 1753221167Sgnn err = ENOMEM; 1754221167Sgnn goto _exit0; 1755221167Sgnn } 1756221167Sgnn 1757221167Sgnn pci_info->reg_map[i] = 1758221167Sgnn (vxge_bus_res_t *) vxge_mem_alloc(sizeof(vxge_bus_res_t)); 1759221167Sgnn 1760221167Sgnn if (pci_info->reg_map[i] == NULL) { 1761221167Sgnn device_printf(vdev->ndev, 1762221167Sgnn "failed to allocate memory bar resources\n"); 1763221167Sgnn err = ENOMEM; 1764221167Sgnn goto _exit0; 1765221167Sgnn } 1766221167Sgnn 1767221167Sgnn ((vxge_bus_res_t *) (pci_info->reg_map[i]))->bus_space_tag = 1768221167Sgnn rman_get_bustag(pci_info->bar_info[i]); 1769221167Sgnn 1770221167Sgnn ((vxge_bus_res_t *) (pci_info->reg_map[i]))->bus_space_handle = 1771221167Sgnn rman_get_bushandle(pci_info->bar_info[i]); 1772221167Sgnn 1773221167Sgnn ((vxge_bus_res_t *) (pci_info->reg_map[i]))->bar_start_addr = 1774221167Sgnn pci_info->bar_info[i]; 1775221167Sgnn 1776221167Sgnn ((vxge_bus_res_t *) (pci_info->reg_map[i]))->bus_res_len = 1777221167Sgnn rman_get_size(pci_info->bar_info[i]); 1778221167Sgnn 1779221167Sgnn_exit0: 1780221167Sgnn return (err); 1781221167Sgnn} 1782221167Sgnn 1783221167Sgnn/* 1784221167Sgnn * vxge_alloc_isr_resources 1785221167Sgnn */ 1786221167Sgnnint 1787221167Sgnnvxge_alloc_isr_resources(vxge_dev_t *vdev) 1788221167Sgnn{ 1789221167Sgnn int i, err = 0, irq_rid; 1790221167Sgnn int msix_vec_reqd, intr_count, msix_count; 1791221167Sgnn 1792221167Sgnn int intr_mode = VXGE_HAL_INTR_MODE_IRQLINE; 1793221167Sgnn 1794221167Sgnn if (vdev->config.intr_mode == VXGE_HAL_INTR_MODE_MSIX) { 1795221167Sgnn /* MSI-X messages supported by device */ 1796221167Sgnn intr_count = pci_msix_count(vdev->ndev); 1797221167Sgnn if (intr_count) { 1798221167Sgnn 1799221167Sgnn msix_vec_reqd = 4 * vdev->no_of_vpath; 1800221167Sgnn if (intr_count >= msix_vec_reqd) { 1801221167Sgnn intr_count = msix_vec_reqd; 1802221167Sgnn 1803221167Sgnn err = pci_alloc_msix(vdev->ndev, &intr_count); 1804221167Sgnn if (err == 0) 1805221167Sgnn intr_mode = VXGE_HAL_INTR_MODE_MSIX; 1806221167Sgnn } 1807221167Sgnn 1808221167Sgnn if ((err != 0) || (intr_count < msix_vec_reqd)) { 1809221167Sgnn device_printf(vdev->ndev, "Unable to allocate " 1810221167Sgnn "msi/x vectors switching to INTA mode\n"); 1811221167Sgnn } 1812221167Sgnn } 1813221167Sgnn } 1814221167Sgnn 1815221167Sgnn err = 0; 1816221167Sgnn vdev->intr_count = 0; 1817221167Sgnn vdev->config.intr_mode = intr_mode; 1818221167Sgnn 1819221167Sgnn switch (vdev->config.intr_mode) { 1820221167Sgnn case VXGE_HAL_INTR_MODE_IRQLINE: 1821221167Sgnn vdev->config.isr_info[0].irq_rid = 0; 1822221167Sgnn vdev->config.isr_info[0].irq_res = 1823221167Sgnn bus_alloc_resource_any(vdev->ndev, SYS_RES_IRQ, 1824221167Sgnn &vdev->config.isr_info[0].irq_rid, 1825221167Sgnn (RF_SHAREABLE | RF_ACTIVE)); 1826221167Sgnn 1827221167Sgnn if (vdev->config.isr_info[0].irq_res == NULL) { 1828221167Sgnn device_printf(vdev->ndev, 1829221167Sgnn "failed to allocate line interrupt resource\n"); 1830221167Sgnn err = ENOMEM; 1831221167Sgnn goto _exit0; 1832221167Sgnn } 1833221167Sgnn vdev->intr_count++; 1834221167Sgnn break; 1835221167Sgnn 1836221167Sgnn case VXGE_HAL_INTR_MODE_MSIX: 1837221167Sgnn msix_count = 0; 1838221167Sgnn for (i = 0; i < vdev->no_of_vpath; i++) { 1839221167Sgnn irq_rid = i * 4; 1840221167Sgnn 1841221167Sgnn vdev->config.isr_info[msix_count].irq_rid = irq_rid + 2; 1842221167Sgnn vdev->config.isr_info[msix_count].irq_res = 1843221167Sgnn bus_alloc_resource_any(vdev->ndev, SYS_RES_IRQ, 1844221167Sgnn &vdev->config.isr_info[msix_count].irq_rid, 1845221167Sgnn (RF_SHAREABLE | RF_ACTIVE)); 1846221167Sgnn 1847221167Sgnn if (vdev->config.isr_info[msix_count].irq_res == NULL) { 1848221167Sgnn device_printf(vdev->ndev, 1849221167Sgnn "allocating bus resource (rid %d) failed\n", 1850221167Sgnn vdev->config.isr_info[msix_count].irq_rid); 1851221167Sgnn err = ENOMEM; 1852221167Sgnn goto _exit0; 1853221167Sgnn } 1854221167Sgnn 1855221167Sgnn vdev->intr_count++; 1856221167Sgnn err = bus_bind_intr(vdev->ndev, 1857221167Sgnn vdev->config.isr_info[msix_count].irq_res, 1858221167Sgnn (i % mp_ncpus)); 1859221167Sgnn if (err != 0) 1860221167Sgnn break; 1861221167Sgnn 1862221167Sgnn msix_count++; 1863221167Sgnn } 1864221167Sgnn 1865221167Sgnn vdev->config.isr_info[msix_count].irq_rid = 3; 1866221167Sgnn vdev->config.isr_info[msix_count].irq_res = 1867221167Sgnn bus_alloc_resource_any(vdev->ndev, SYS_RES_IRQ, 1868221167Sgnn &vdev->config.isr_info[msix_count].irq_rid, 1869221167Sgnn (RF_SHAREABLE | RF_ACTIVE)); 1870221167Sgnn 1871221167Sgnn if (vdev->config.isr_info[msix_count].irq_res == NULL) { 1872221167Sgnn device_printf(vdev->ndev, 1873221167Sgnn "allocating bus resource (rid %d) failed\n", 1874221167Sgnn vdev->config.isr_info[msix_count].irq_rid); 1875221167Sgnn err = ENOMEM; 1876221167Sgnn goto _exit0; 1877221167Sgnn } 1878221167Sgnn 1879221167Sgnn vdev->intr_count++; 1880221167Sgnn err = bus_bind_intr(vdev->ndev, 1881221167Sgnn vdev->config.isr_info[msix_count].irq_res, (i % mp_ncpus)); 1882221167Sgnn 1883221167Sgnn break; 1884221167Sgnn } 1885221167Sgnn 1886221167Sgnn vdev->device_config->intr_mode = vdev->config.intr_mode; 1887221167Sgnn 1888221167Sgnn_exit0: 1889221167Sgnn return (err); 1890221167Sgnn} 1891221167Sgnn 1892221167Sgnn/* 1893221167Sgnn * vxge_free_resources 1894221167Sgnn * Undo what-all we did during load/attach 1895221167Sgnn */ 1896221167Sgnnvoid 1897221167Sgnnvxge_free_resources(device_t ndev, vxge_free_resources_e vxge_free_resource) 1898221167Sgnn{ 1899221167Sgnn int i; 1900221167Sgnn vxge_dev_t *vdev; 1901221167Sgnn 1902221167Sgnn vdev = (vxge_dev_t *) device_get_softc(ndev); 1903221167Sgnn 1904221167Sgnn switch (vxge_free_resource) { 1905221167Sgnn case VXGE_FREE_ALL: 1906221167Sgnn for (i = 0; i < vdev->intr_count; i++) { 1907221167Sgnn bus_teardown_intr(ndev, 1908221167Sgnn vdev->config.isr_info[i].irq_res, 1909221167Sgnn vdev->config.isr_info[i].irq_handle); 1910221167Sgnn } 1911221167Sgnn /* FALLTHROUGH */ 1912221167Sgnn 1913221167Sgnn case VXGE_FREE_INTERFACE: 1914221167Sgnn ether_ifdetach(vdev->ifp); 1915221167Sgnn bus_generic_detach(ndev); 1916221167Sgnn if_free(vdev->ifp); 1917221167Sgnn /* FALLTHROUGH */ 1918221167Sgnn 1919221167Sgnn case VXGE_FREE_MEDIA: 1920221167Sgnn ifmedia_removeall(&vdev->media); 1921221167Sgnn /* FALLTHROUGH */ 1922221167Sgnn 1923221167Sgnn case VXGE_FREE_MUTEX: 1924221167Sgnn vxge_mutex_destroy(vdev); 1925221167Sgnn /* FALLTHROUGH */ 1926221167Sgnn 1927221167Sgnn case VXGE_FREE_VPATH: 1928221167Sgnn vxge_mem_free(vdev->vpaths, 1929221167Sgnn vdev->no_of_vpath * sizeof(vxge_vpath_t)); 1930221167Sgnn /* FALLTHROUGH */ 1931221167Sgnn 1932221167Sgnn case VXGE_FREE_TERMINATE_DEVICE: 1933221167Sgnn if (vdev->devh != NULL) { 1934221167Sgnn vxge_hal_device_private_set(vdev->devh, 0); 1935221167Sgnn vxge_hal_device_terminate(vdev->devh); 1936221167Sgnn } 1937221167Sgnn /* FALLTHROUGH */ 1938221167Sgnn 1939221167Sgnn case VXGE_FREE_ISR_RESOURCE: 1940221167Sgnn vxge_free_isr_resources(vdev); 1941221167Sgnn /* FALLTHROUGH */ 1942221167Sgnn 1943221167Sgnn case VXGE_FREE_BAR2: 1944221167Sgnn vxge_free_bar_resources(vdev, 2); 1945221167Sgnn /* FALLTHROUGH */ 1946221167Sgnn 1947221167Sgnn case VXGE_FREE_BAR1: 1948221167Sgnn vxge_free_bar_resources(vdev, 1); 1949221167Sgnn /* FALLTHROUGH */ 1950221167Sgnn 1951221167Sgnn case VXGE_FREE_BAR0: 1952221167Sgnn vxge_free_bar_resources(vdev, 0); 1953221167Sgnn /* FALLTHROUGH */ 1954221167Sgnn 1955221167Sgnn case VXGE_FREE_PCI_INFO: 1956221167Sgnn vxge_mem_free(vdev->pdev, sizeof(vxge_pci_info_t)); 1957221167Sgnn /* FALLTHROUGH */ 1958221167Sgnn 1959221167Sgnn case VXGE_FREE_DEVICE_CONFIG: 1960221167Sgnn vxge_mem_free(vdev->device_config, 1961221167Sgnn sizeof(vxge_hal_device_config_t)); 1962221167Sgnn /* FALLTHROUGH */ 1963221167Sgnn 1964221167Sgnn case VXGE_DISABLE_PCI_BUSMASTER: 1965221167Sgnn pci_disable_busmaster(ndev); 1966221167Sgnn /* FALLTHROUGH */ 1967221167Sgnn 1968221167Sgnn case VXGE_FREE_TERMINATE_DRIVER: 1969221167Sgnn if (vxge_dev_ref_count) { 1970221167Sgnn --vxge_dev_ref_count; 1971221167Sgnn if (0 == vxge_dev_ref_count) 1972221167Sgnn vxge_hal_driver_terminate(); 1973221167Sgnn } 1974221167Sgnn /* FALLTHROUGH */ 1975221167Sgnn 1976221167Sgnn default: 1977221167Sgnn case VXGE_FREE_NONE: 1978221167Sgnn break; 1979221167Sgnn /* NOTREACHED */ 1980221167Sgnn } 1981221167Sgnn} 1982221167Sgnn 1983221167Sgnnvoid 1984221167Sgnnvxge_free_isr_resources(vxge_dev_t *vdev) 1985221167Sgnn{ 1986221167Sgnn int i; 1987221167Sgnn 1988221167Sgnn switch (vdev->config.intr_mode) { 1989221167Sgnn case VXGE_HAL_INTR_MODE_IRQLINE: 1990221167Sgnn if (vdev->config.isr_info[0].irq_res) { 1991221167Sgnn bus_release_resource(vdev->ndev, SYS_RES_IRQ, 1992221167Sgnn vdev->config.isr_info[0].irq_rid, 1993221167Sgnn vdev->config.isr_info[0].irq_res); 1994221167Sgnn 1995221167Sgnn vdev->config.isr_info[0].irq_res = NULL; 1996221167Sgnn } 1997221167Sgnn break; 1998221167Sgnn 1999221167Sgnn case VXGE_HAL_INTR_MODE_MSIX: 2000221167Sgnn for (i = 0; i < vdev->intr_count; i++) { 2001221167Sgnn if (vdev->config.isr_info[i].irq_res) { 2002221167Sgnn bus_release_resource(vdev->ndev, SYS_RES_IRQ, 2003221167Sgnn vdev->config.isr_info[i].irq_rid, 2004221167Sgnn vdev->config.isr_info[i].irq_res); 2005221167Sgnn 2006221167Sgnn vdev->config.isr_info[i].irq_res = NULL; 2007221167Sgnn } 2008221167Sgnn } 2009221167Sgnn 2010221167Sgnn if (vdev->intr_count) 2011221167Sgnn pci_release_msi(vdev->ndev); 2012221167Sgnn 2013221167Sgnn break; 2014221167Sgnn } 2015221167Sgnn} 2016221167Sgnn 2017221167Sgnnvoid 2018221167Sgnnvxge_free_bar_resources(vxge_dev_t *vdev, int i) 2019221167Sgnn{ 2020221167Sgnn int res_id = 0; 2021221167Sgnn vxge_pci_info_t *pci_info = vdev->pdev; 2022221167Sgnn 2023221167Sgnn res_id = PCIR_BAR((i == 0) ? 0 : (i * 2)); 2024221167Sgnn 2025221167Sgnn if (pci_info->bar_info[i]) 2026221167Sgnn bus_release_resource(vdev->ndev, SYS_RES_MEMORY, 2027221167Sgnn res_id, pci_info->bar_info[i]); 2028221167Sgnn 2029221167Sgnn vxge_mem_free(pci_info->reg_map[i], sizeof(vxge_bus_res_t)); 2030221167Sgnn} 2031221167Sgnn 2032221167Sgnn/* 2033221167Sgnn * vxge_init_mutex 2034221167Sgnn * Initializes mutexes used in driver 2035221167Sgnn */ 2036221167Sgnnvoid 2037221167Sgnnvxge_mutex_init(vxge_dev_t *vdev) 2038221167Sgnn{ 2039221167Sgnn int i; 2040221167Sgnn 2041221167Sgnn snprintf(vdev->mtx_drv_name, sizeof(vdev->mtx_drv_name), 2042221167Sgnn "%s_drv", vdev->ndev_name); 2043221167Sgnn 2044221167Sgnn mtx_init(&vdev->mtx_drv, vdev->mtx_drv_name, 2045221167Sgnn MTX_NETWORK_LOCK, MTX_DEF); 2046221167Sgnn 2047221167Sgnn for (i = 0; i < vdev->no_of_vpath; i++) { 2048221167Sgnn snprintf(vdev->vpaths[i].mtx_tx_name, 2049221167Sgnn sizeof(vdev->vpaths[i].mtx_tx_name), "%s_tx_%d", 2050221167Sgnn vdev->ndev_name, i); 2051221167Sgnn 2052221167Sgnn mtx_init(&vdev->vpaths[i].mtx_tx, 2053221167Sgnn vdev->vpaths[i].mtx_tx_name, NULL, MTX_DEF); 2054221167Sgnn } 2055221167Sgnn} 2056221167Sgnn 2057221167Sgnn/* 2058221167Sgnn * vxge_mutex_destroy 2059221167Sgnn * Destroys mutexes used in driver 2060221167Sgnn */ 2061221167Sgnnvoid 2062221167Sgnnvxge_mutex_destroy(vxge_dev_t *vdev) 2063221167Sgnn{ 2064221167Sgnn int i; 2065221167Sgnn 2066221167Sgnn for (i = 0; i < vdev->no_of_vpath; i++) 2067221167Sgnn VXGE_TX_LOCK_DESTROY(&(vdev->vpaths[i])); 2068221167Sgnn 2069221167Sgnn VXGE_DRV_LOCK_DESTROY(vdev); 2070221167Sgnn} 2071221167Sgnn 2072221167Sgnn/* 2073221167Sgnn * vxge_rth_config 2074221167Sgnn */ 2075221167Sgnnvxge_hal_status_e 2076221167Sgnnvxge_rth_config(vxge_dev_t *vdev) 2077221167Sgnn{ 2078221167Sgnn int i; 2079221167Sgnn vxge_hal_vpath_h vpath_handle; 2080221167Sgnn vxge_hal_rth_hash_types_t hash_types; 2081221167Sgnn vxge_hal_status_e status = VXGE_HAL_OK; 2082221167Sgnn u8 mtable[256] = {0}; 2083221167Sgnn 2084221167Sgnn /* Filling matable with bucket-to-vpath mapping */ 2085221167Sgnn vdev->config.rth_bkt_sz = VXGE_DEFAULT_RTH_BUCKET_SIZE; 2086221167Sgnn 2087221167Sgnn for (i = 0; i < (1 << vdev->config.rth_bkt_sz); i++) 2088221167Sgnn mtable[i] = i % vdev->no_of_vpath; 2089221167Sgnn 2090221167Sgnn /* Fill RTH hash types */ 2091221167Sgnn hash_types.hash_type_tcpipv4_en = VXGE_HAL_RING_HASH_TYPE_TCP_IPV4; 2092221167Sgnn hash_types.hash_type_tcpipv6_en = VXGE_HAL_RING_HASH_TYPE_TCP_IPV6; 2093221167Sgnn hash_types.hash_type_tcpipv6ex_en = VXGE_HAL_RING_HASH_TYPE_TCP_IPV6_EX; 2094221167Sgnn hash_types.hash_type_ipv4_en = VXGE_HAL_RING_HASH_TYPE_IPV4; 2095221167Sgnn hash_types.hash_type_ipv6_en = VXGE_HAL_RING_HASH_TYPE_IPV6; 2096221167Sgnn hash_types.hash_type_ipv6ex_en = VXGE_HAL_RING_HASH_TYPE_IPV6_EX; 2097221167Sgnn 2098221167Sgnn /* set indirection table, bucket-to-vpath mapping */ 2099221167Sgnn status = vxge_hal_vpath_rts_rth_itable_set(vdev->vpath_handles, 2100221167Sgnn vdev->no_of_vpath, mtable, 2101221167Sgnn ((u32) (1 << vdev->config.rth_bkt_sz))); 2102221167Sgnn 2103221167Sgnn if (status != VXGE_HAL_OK) { 2104221167Sgnn device_printf(vdev->ndev, "rth configuration failed\n"); 2105221167Sgnn goto _exit0; 2106221167Sgnn } 2107221167Sgnn for (i = 0; i < vdev->no_of_vpath; i++) { 2108221167Sgnn vpath_handle = vxge_vpath_handle_get(vdev, i); 2109221167Sgnn if (!vpath_handle) 2110221167Sgnn continue; 2111221167Sgnn 2112221167Sgnn status = vxge_hal_vpath_rts_rth_set(vpath_handle, 2113221167Sgnn RTH_ALG_JENKINS, 2114221167Sgnn &hash_types, vdev->config.rth_bkt_sz, TRUE); 2115221167Sgnn if (status != VXGE_HAL_OK) { 2116221167Sgnn device_printf(vdev->ndev, 2117221167Sgnn "rth configuration failed for vpath (%d)\n", 2118221167Sgnn vdev->vpaths[i].vp_id); 2119221167Sgnn break; 2120221167Sgnn } 2121221167Sgnn } 2122221167Sgnn 2123221167Sgnn_exit0: 2124221167Sgnn return (status); 2125221167Sgnn} 2126221167Sgnn 2127221167Sgnn/* 2128221167Sgnn * vxge_vpath_config 2129221167Sgnn * Sets HAL parameter values from kenv 2130221167Sgnn */ 2131221167Sgnnvoid 2132221167Sgnnvxge_vpath_config(vxge_dev_t *vdev) 2133221167Sgnn{ 2134221167Sgnn int i; 2135221167Sgnn u32 no_of_vpath = 0; 2136221167Sgnn vxge_hal_vp_config_t *vp_config; 2137221167Sgnn vxge_hal_device_config_t *device_config = vdev->device_config; 2138221167Sgnn 2139221167Sgnn device_config->debug_level = VXGE_TRACE; 2140221167Sgnn device_config->debug_mask = VXGE_COMPONENT_ALL; 2141221167Sgnn device_config->device_poll_millis = VXGE_DEFAULT_DEVICE_POLL_MILLIS; 2142221167Sgnn 2143221167Sgnn vdev->config.no_of_vpath = 2144221167Sgnn min(vdev->config.no_of_vpath, vdev->max_supported_vpath); 2145221167Sgnn 2146221167Sgnn for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) { 2147221167Sgnn vp_config = &(device_config->vp_config[i]); 2148221167Sgnn vp_config->fifo.enable = VXGE_HAL_FIFO_DISABLE; 2149221167Sgnn vp_config->ring.enable = VXGE_HAL_RING_DISABLE; 2150221167Sgnn } 2151221167Sgnn 2152221167Sgnn for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) { 2153221167Sgnn if (no_of_vpath >= vdev->config.no_of_vpath) 2154221167Sgnn break; 2155221167Sgnn 2156221167Sgnn if (!bVAL1(vdev->config.hw_info.vpath_mask, i)) 2157221167Sgnn continue; 2158221167Sgnn 2159221167Sgnn no_of_vpath++; 2160221167Sgnn vp_config = &(device_config->vp_config[i]); 2161221167Sgnn vp_config->mtu = VXGE_HAL_DEFAULT_MTU; 2162221167Sgnn vp_config->ring.enable = VXGE_HAL_RING_ENABLE; 2163221167Sgnn vp_config->ring.post_mode = VXGE_HAL_RING_POST_MODE_DOORBELL; 2164221167Sgnn vp_config->ring.buffer_mode = VXGE_HAL_RING_RXD_BUFFER_MODE_1; 2165221167Sgnn vp_config->ring.ring_length = 2166221167Sgnn vxge_ring_length_get(VXGE_HAL_RING_RXD_BUFFER_MODE_1); 2167221167Sgnn vp_config->ring.scatter_mode = VXGE_HAL_RING_SCATTER_MODE_A; 2168221167Sgnn vp_config->rpa_all_vid_en = VXGE_DEFAULT_ALL_VID_ENABLE; 2169221167Sgnn vp_config->rpa_strip_vlan_tag = VXGE_DEFAULT_STRIP_VLAN_TAG; 2170221167Sgnn vp_config->rpa_ucast_all_addr_en = 2171221167Sgnn VXGE_HAL_VPATH_RPA_UCAST_ALL_ADDR_DISABLE; 2172221167Sgnn 2173221167Sgnn vp_config->rti.intr_enable = VXGE_HAL_TIM_INTR_ENABLE; 2174221167Sgnn vp_config->rti.txfrm_cnt_en = VXGE_HAL_TXFRM_CNT_EN_ENABLE; 2175221167Sgnn vp_config->rti.util_sel = 2176221167Sgnn VXGE_HAL_TIM_UTIL_SEL_LEGACY_RX_NET_UTIL; 2177221167Sgnn 2178221167Sgnn vp_config->rti.uec_a = VXGE_DEFAULT_RTI_RX_UFC_A; 2179221167Sgnn vp_config->rti.uec_b = VXGE_DEFAULT_RTI_RX_UFC_B; 2180221167Sgnn vp_config->rti.uec_c = VXGE_DEFAULT_RTI_RX_UFC_C; 2181221167Sgnn vp_config->rti.uec_d = VXGE_DEFAULT_RTI_RX_UFC_D; 2182221167Sgnn 2183221167Sgnn vp_config->rti.urange_a = VXGE_DEFAULT_RTI_RX_URANGE_A; 2184221167Sgnn vp_config->rti.urange_b = VXGE_DEFAULT_RTI_RX_URANGE_B; 2185221167Sgnn vp_config->rti.urange_c = VXGE_DEFAULT_RTI_RX_URANGE_C; 2186221167Sgnn 2187221167Sgnn vp_config->rti.timer_ac_en = VXGE_HAL_TIM_TIMER_AC_ENABLE; 2188221167Sgnn vp_config->rti.timer_ci_en = VXGE_HAL_TIM_TIMER_CI_ENABLE; 2189221167Sgnn 2190221167Sgnn vp_config->rti.btimer_val = 2191221167Sgnn (VXGE_DEFAULT_RTI_BTIMER_VAL * 1000) / 272; 2192221167Sgnn vp_config->rti.rtimer_val = 2193221167Sgnn (VXGE_DEFAULT_RTI_RTIMER_VAL * 1000) / 272; 2194221167Sgnn vp_config->rti.ltimer_val = 2195221167Sgnn (VXGE_DEFAULT_RTI_LTIMER_VAL * 1000) / 272; 2196221167Sgnn 2197221167Sgnn if ((no_of_vpath > 1) && (VXGE_DEFAULT_CONFIG_MQ_ENABLE == 0)) 2198221167Sgnn continue; 2199221167Sgnn 2200221167Sgnn vp_config->fifo.enable = VXGE_HAL_FIFO_ENABLE; 2201221167Sgnn vp_config->fifo.max_aligned_frags = 2202221167Sgnn VXGE_DEFAULT_FIFO_ALIGNED_FRAGS; 2203221167Sgnn 2204221167Sgnn vp_config->tti.intr_enable = VXGE_HAL_TIM_INTR_ENABLE; 2205221167Sgnn vp_config->tti.txfrm_cnt_en = VXGE_HAL_TXFRM_CNT_EN_ENABLE; 2206221167Sgnn vp_config->tti.util_sel = 2207221167Sgnn VXGE_HAL_TIM_UTIL_SEL_LEGACY_TX_NET_UTIL; 2208221167Sgnn 2209221167Sgnn vp_config->tti.uec_a = VXGE_DEFAULT_TTI_TX_UFC_A; 2210221167Sgnn vp_config->tti.uec_b = VXGE_DEFAULT_TTI_TX_UFC_B; 2211221167Sgnn vp_config->tti.uec_c = VXGE_DEFAULT_TTI_TX_UFC_C; 2212221167Sgnn vp_config->tti.uec_d = VXGE_DEFAULT_TTI_TX_UFC_D; 2213221167Sgnn 2214221167Sgnn vp_config->tti.urange_a = VXGE_DEFAULT_TTI_TX_URANGE_A; 2215221167Sgnn vp_config->tti.urange_b = VXGE_DEFAULT_TTI_TX_URANGE_B; 2216221167Sgnn vp_config->tti.urange_c = VXGE_DEFAULT_TTI_TX_URANGE_C; 2217221167Sgnn 2218221167Sgnn vp_config->tti.timer_ac_en = VXGE_HAL_TIM_TIMER_AC_ENABLE; 2219221167Sgnn vp_config->tti.timer_ci_en = VXGE_HAL_TIM_TIMER_CI_ENABLE; 2220221167Sgnn 2221221167Sgnn vp_config->tti.btimer_val = 2222221167Sgnn (VXGE_DEFAULT_TTI_BTIMER_VAL * 1000) / 272; 2223221167Sgnn vp_config->tti.rtimer_val = 2224221167Sgnn (VXGE_DEFAULT_TTI_RTIMER_VAL * 1000) / 272; 2225221167Sgnn vp_config->tti.ltimer_val = 2226221167Sgnn (VXGE_DEFAULT_TTI_LTIMER_VAL * 1000) / 272; 2227221167Sgnn } 2228221167Sgnn 2229221167Sgnn vdev->no_of_vpath = no_of_vpath; 2230221167Sgnn 2231221167Sgnn if (vdev->no_of_vpath == 1) 2232221167Sgnn vdev->config.tx_steering = 0; 2233221167Sgnn 2234221167Sgnn if (vdev->config.rth_enable && (vdev->no_of_vpath > 1)) { 2235221167Sgnn device_config->rth_en = VXGE_HAL_RTH_ENABLE; 2236221167Sgnn device_config->rth_it_type = VXGE_HAL_RTH_IT_TYPE_MULTI_IT; 2237221167Sgnn } 2238221167Sgnn 2239221167Sgnn vdev->config.rth_enable = device_config->rth_en; 2240221167Sgnn} 2241221167Sgnn 2242221167Sgnn/* 2243221167Sgnn * vxge_vpath_cb_fn 2244221167Sgnn * Virtual path Callback function 2245221167Sgnn */ 2246221167Sgnn/* ARGSUSED */ 2247221167Sgnnstatic vxge_hal_status_e 2248221167Sgnnvxge_vpath_cb_fn(vxge_hal_client_h client_handle, vxge_hal_up_msg_h msgh, 2249221167Sgnn vxge_hal_message_type_e msg_type, vxge_hal_obj_id_t obj_id, 2250221167Sgnn vxge_hal_result_e result, vxge_hal_opaque_handle_t *opaque_handle) 2251221167Sgnn{ 2252221167Sgnn return (VXGE_HAL_OK); 2253221167Sgnn} 2254221167Sgnn 2255221167Sgnn/* 2256221167Sgnn * vxge_vpath_open 2257221167Sgnn */ 2258221167Sgnnint 2259221167Sgnnvxge_vpath_open(vxge_dev_t *vdev) 2260221167Sgnn{ 2261221167Sgnn int i, err = EINVAL; 2262221167Sgnn u64 func_id; 2263221167Sgnn 2264221167Sgnn vxge_vpath_t *vpath; 2265221167Sgnn vxge_hal_vpath_attr_t vpath_attr; 2266221167Sgnn vxge_hal_status_e status = VXGE_HAL_OK; 2267221167Sgnn struct lro_ctrl *lro = NULL; 2268221167Sgnn 2269221167Sgnn bzero(&vpath_attr, sizeof(vxge_hal_vpath_attr_t)); 2270221167Sgnn 2271221167Sgnn for (i = 0; i < vdev->no_of_vpath; i++) { 2272221167Sgnn 2273221167Sgnn vpath = &(vdev->vpaths[i]); 2274221167Sgnn lro = &vpath->lro; 2275221167Sgnn 2276221167Sgnn /* Vpath vpath_attr: FIFO */ 2277221167Sgnn vpath_attr.vp_id = vpath->vp_id; 2278221167Sgnn vpath_attr.fifo_attr.callback = vxge_tx_compl; 2279221167Sgnn vpath_attr.fifo_attr.txdl_init = vxge_tx_replenish; 2280221167Sgnn vpath_attr.fifo_attr.txdl_term = vxge_tx_term; 2281221167Sgnn vpath_attr.fifo_attr.userdata = vpath; 2282221167Sgnn vpath_attr.fifo_attr.per_txdl_space = sizeof(vxge_txdl_priv_t); 2283221167Sgnn 2284221167Sgnn /* Vpath vpath_attr: Ring */ 2285221167Sgnn vpath_attr.ring_attr.callback = vxge_rx_compl; 2286221167Sgnn vpath_attr.ring_attr.rxd_init = vxge_rx_replenish; 2287221167Sgnn vpath_attr.ring_attr.rxd_term = vxge_rx_term; 2288221167Sgnn vpath_attr.ring_attr.userdata = vpath; 2289221167Sgnn vpath_attr.ring_attr.per_rxd_space = sizeof(vxge_rxd_priv_t); 2290221167Sgnn 2291221167Sgnn err = vxge_dma_tags_create(vpath); 2292221167Sgnn if (err != 0) { 2293221167Sgnn device_printf(vdev->ndev, 2294221167Sgnn "failed to create dma tags\n"); 2295221167Sgnn break; 2296221167Sgnn } 2297221167Sgnn#if __FreeBSD_version >= 800000 2298221167Sgnn vpath->br = buf_ring_alloc(VXGE_DEFAULT_BR_SIZE, M_DEVBUF, 2299221167Sgnn M_WAITOK, &vpath->mtx_tx); 2300221167Sgnn if (vpath->br == NULL) { 2301221167Sgnn err = ENOMEM; 2302221167Sgnn break; 2303221167Sgnn } 2304221167Sgnn#endif 2305221167Sgnn status = vxge_hal_vpath_open(vdev->devh, &vpath_attr, 2306221167Sgnn (vxge_hal_vpath_callback_f) vxge_vpath_cb_fn, 2307221167Sgnn NULL, &vpath->handle); 2308221167Sgnn if (status != VXGE_HAL_OK) { 2309221167Sgnn device_printf(vdev->ndev, 2310221167Sgnn "failed to open vpath (%d)\n", vpath->vp_id); 2311221167Sgnn err = EPERM; 2312221167Sgnn break; 2313221167Sgnn } 2314221167Sgnn vpath->is_open = TRUE; 2315221167Sgnn vdev->vpath_handles[i] = vpath->handle; 2316221167Sgnn 2317221167Sgnn vpath->tx_ticks = ticks; 2318221167Sgnn vpath->rx_ticks = ticks; 2319221167Sgnn 2320221167Sgnn vpath->tti_rtimer_val = VXGE_DEFAULT_TTI_RTIMER_VAL; 2321221167Sgnn vpath->tti_rtimer_val = VXGE_DEFAULT_TTI_RTIMER_VAL; 2322221167Sgnn 2323221167Sgnn vpath->tx_intr_coalesce = vdev->config.intr_coalesce; 2324221167Sgnn vpath->rx_intr_coalesce = vdev->config.intr_coalesce; 2325221167Sgnn 2326221167Sgnn func_id = vdev->config.hw_info.func_id; 2327221167Sgnn 2328221167Sgnn if (vdev->config.low_latency && 2329221167Sgnn (vdev->config.bw_info[func_id].priority == 2330221167Sgnn VXGE_DEFAULT_VPATH_PRIORITY_HIGH)) { 2331221167Sgnn vpath->tx_intr_coalesce = 0; 2332221167Sgnn } 2333221167Sgnn 2334221167Sgnn if (vdev->ifp->if_capenable & IFCAP_LRO) { 2335221167Sgnn err = tcp_lro_init(lro); 2336221167Sgnn if (err != 0) { 2337221167Sgnn device_printf(vdev->ndev, 2338221167Sgnn "LRO Initialization failed!\n"); 2339221167Sgnn break; 2340221167Sgnn } 2341221167Sgnn vpath->lro_enable = TRUE; 2342221167Sgnn lro->ifp = vdev->ifp; 2343221167Sgnn } 2344221167Sgnn } 2345221167Sgnn 2346221167Sgnn return (err); 2347221167Sgnn} 2348221167Sgnn 2349221167Sgnnvoid 2350221167Sgnnvxge_tso_config(vxge_dev_t *vdev) 2351221167Sgnn{ 2352221167Sgnn u32 func_id, priority; 2353221167Sgnn vxge_hal_status_e status = VXGE_HAL_OK; 2354221167Sgnn 2355221167Sgnn vdev->ifp->if_capabilities |= IFCAP_TSO4; 2356221167Sgnn 2357221167Sgnn status = vxge_bw_priority_get(vdev, NULL); 2358221167Sgnn if (status == VXGE_HAL_OK) { 2359221167Sgnn 2360221167Sgnn func_id = vdev->config.hw_info.func_id; 2361221167Sgnn priority = vdev->config.bw_info[func_id].priority; 2362221167Sgnn 2363221167Sgnn if (priority != VXGE_DEFAULT_VPATH_PRIORITY_HIGH) 2364221167Sgnn vdev->ifp->if_capabilities &= ~IFCAP_TSO4; 2365221167Sgnn } 2366221167Sgnn 2367221167Sgnn#if __FreeBSD_version >= 800000 2368221167Sgnn if (vdev->ifp->if_capabilities & IFCAP_TSO4) 2369221167Sgnn vdev->ifp->if_capabilities |= IFCAP_VLAN_HWTSO; 2370221167Sgnn#endif 2371221167Sgnn 2372221167Sgnn} 2373221167Sgnn 2374221167Sgnnvxge_hal_status_e 2375221167Sgnnvxge_bw_priority_get(vxge_dev_t *vdev, vxge_bw_info_t *bw_info) 2376221167Sgnn{ 2377221167Sgnn u32 priority, bandwidth; 2378221167Sgnn u32 vpath_count; 2379221167Sgnn 2380221167Sgnn u64 func_id, func_mode, vpath_list[VXGE_HAL_MAX_VIRTUAL_PATHS]; 2381221167Sgnn vxge_hal_status_e status = VXGE_HAL_OK; 2382221167Sgnn 2383221167Sgnn func_id = vdev->config.hw_info.func_id; 2384221167Sgnn if (bw_info) { 2385221167Sgnn func_id = bw_info->func_id; 2386221167Sgnn func_mode = vdev->config.hw_info.function_mode; 2387221167Sgnn if ((is_single_func(func_mode)) && (func_id > 0)) 2388221167Sgnn return (VXGE_HAL_FAIL); 2389221167Sgnn } 2390221167Sgnn 2391221167Sgnn if (vdev->hw_fw_version >= VXGE_FW_VERSION(1, 8, 0)) { 2392221167Sgnn 2393221167Sgnn status = vxge_hal_vf_rx_bw_get(vdev->devh, 2394221167Sgnn func_id, &bandwidth, &priority); 2395221167Sgnn 2396221167Sgnn } else { 2397221167Sgnn 2398221167Sgnn status = vxge_hal_get_vpath_list(vdev->devh, 2399221167Sgnn func_id, vpath_list, &vpath_count); 2400221167Sgnn 2401221167Sgnn if (status == VXGE_HAL_OK) { 2402221167Sgnn status = vxge_hal_bw_priority_get(vdev->devh, 2403221167Sgnn vpath_list[0], &bandwidth, &priority); 2404221167Sgnn } 2405221167Sgnn } 2406221167Sgnn 2407221167Sgnn if (status == VXGE_HAL_OK) { 2408221167Sgnn if (bw_info) { 2409221167Sgnn bw_info->priority = priority; 2410221167Sgnn bw_info->bandwidth = bandwidth; 2411221167Sgnn } else { 2412221167Sgnn vdev->config.bw_info[func_id].priority = priority; 2413221167Sgnn vdev->config.bw_info[func_id].bandwidth = bandwidth; 2414221167Sgnn } 2415221167Sgnn } 2416221167Sgnn 2417221167Sgnn return (status); 2418221167Sgnn} 2419221167Sgnn 2420221167Sgnn/* 2421221167Sgnn * close vpaths 2422221167Sgnn */ 2423221167Sgnnvoid 2424221167Sgnnvxge_vpath_close(vxge_dev_t *vdev) 2425221167Sgnn{ 2426221167Sgnn int i; 2427221167Sgnn vxge_vpath_t *vpath; 2428221167Sgnn 2429221167Sgnn for (i = 0; i < vdev->no_of_vpath; i++) { 2430221167Sgnn 2431221167Sgnn vpath = &(vdev->vpaths[i]); 2432221167Sgnn if (vpath->handle) 2433221167Sgnn vxge_hal_vpath_close(vpath->handle); 2434221167Sgnn 2435221167Sgnn#if __FreeBSD_version >= 800000 2436221167Sgnn if (vpath->br != NULL) 2437221167Sgnn buf_ring_free(vpath->br, M_DEVBUF); 2438221167Sgnn#endif 2439221167Sgnn /* Free LRO memory */ 2440221167Sgnn if (vpath->lro_enable) 2441221167Sgnn tcp_lro_free(&vpath->lro); 2442221167Sgnn 2443221167Sgnn if (vpath->dma_tag_rx) { 2444221167Sgnn bus_dmamap_destroy(vpath->dma_tag_rx, 2445221167Sgnn vpath->extra_dma_map); 2446221167Sgnn bus_dma_tag_destroy(vpath->dma_tag_rx); 2447221167Sgnn } 2448221167Sgnn 2449221167Sgnn if (vpath->dma_tag_tx) 2450221167Sgnn bus_dma_tag_destroy(vpath->dma_tag_tx); 2451221167Sgnn 2452221167Sgnn vpath->handle = NULL; 2453221167Sgnn vpath->is_open = FALSE; 2454221167Sgnn } 2455221167Sgnn} 2456221167Sgnn 2457221167Sgnn/* 2458221167Sgnn * reset vpaths 2459221167Sgnn */ 2460221167Sgnnvoid 2461221167Sgnnvxge_vpath_reset(vxge_dev_t *vdev) 2462221167Sgnn{ 2463221167Sgnn int i; 2464221167Sgnn vxge_hal_vpath_h vpath_handle; 2465221167Sgnn vxge_hal_status_e status = VXGE_HAL_OK; 2466221167Sgnn 2467221167Sgnn for (i = 0; i < vdev->no_of_vpath; i++) { 2468221167Sgnn vpath_handle = vxge_vpath_handle_get(vdev, i); 2469221167Sgnn if (!vpath_handle) 2470221167Sgnn continue; 2471221167Sgnn 2472221167Sgnn status = vxge_hal_vpath_reset(vpath_handle); 2473221167Sgnn if (status != VXGE_HAL_OK) 2474221167Sgnn device_printf(vdev->ndev, 2475221167Sgnn "failed to reset vpath :%d\n", i); 2476221167Sgnn } 2477221167Sgnn} 2478221167Sgnn 2479221167Sgnnstatic inline int 2480221167Sgnnvxge_vpath_get(vxge_dev_t *vdev, mbuf_t mhead) 2481221167Sgnn{ 2482221167Sgnn struct tcphdr *th = NULL; 2483221167Sgnn struct udphdr *uh = NULL; 2484221167Sgnn struct ip *ip = NULL; 2485221167Sgnn struct ip6_hdr *ip6 = NULL; 2486221167Sgnn struct ether_vlan_header *eth = NULL; 2487221167Sgnn void *ulp = NULL; 2488221167Sgnn 2489221167Sgnn int ehdrlen, iphlen = 0; 2490221167Sgnn u8 ipproto = 0; 2491221167Sgnn u16 etype, src_port, dst_port; 2492221167Sgnn u16 queue_len, counter = 0; 2493221167Sgnn 2494221167Sgnn src_port = dst_port = 0; 2495221167Sgnn queue_len = vdev->no_of_vpath; 2496221167Sgnn 2497221167Sgnn eth = mtod(mhead, struct ether_vlan_header *); 2498221167Sgnn if (eth->evl_encap_proto == htons(ETHERTYPE_VLAN)) { 2499221167Sgnn etype = ntohs(eth->evl_proto); 2500221167Sgnn ehdrlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN; 2501221167Sgnn } else { 2502221167Sgnn etype = ntohs(eth->evl_encap_proto); 2503221167Sgnn ehdrlen = ETHER_HDR_LEN; 2504221167Sgnn } 2505221167Sgnn 2506221167Sgnn switch (etype) { 2507221167Sgnn case ETHERTYPE_IP: 2508221167Sgnn ip = (struct ip *) (mhead->m_data + ehdrlen); 2509221167Sgnn iphlen = ip->ip_hl << 2; 2510221167Sgnn ipproto = ip->ip_p; 2511221167Sgnn th = (struct tcphdr *) ((caddr_t)ip + iphlen); 2512221167Sgnn uh = (struct udphdr *) ((caddr_t)ip + iphlen); 2513221167Sgnn break; 2514221167Sgnn 2515221167Sgnn case ETHERTYPE_IPV6: 2516221167Sgnn ip6 = (struct ip6_hdr *) (mhead->m_data + ehdrlen); 2517221167Sgnn iphlen = sizeof(struct ip6_hdr); 2518221167Sgnn ipproto = ip6->ip6_nxt; 2519221167Sgnn 2520221167Sgnn ulp = mtod(mhead, char *) + iphlen; 2521221167Sgnn th = ((struct tcphdr *) (ulp)); 2522221167Sgnn uh = ((struct udphdr *) (ulp)); 2523221167Sgnn break; 2524221167Sgnn 2525221167Sgnn default: 2526221167Sgnn break; 2527221167Sgnn } 2528221167Sgnn 2529221167Sgnn switch (ipproto) { 2530221167Sgnn case IPPROTO_TCP: 2531221167Sgnn src_port = th->th_sport; 2532221167Sgnn dst_port = th->th_dport; 2533221167Sgnn break; 2534221167Sgnn 2535221167Sgnn case IPPROTO_UDP: 2536221167Sgnn src_port = uh->uh_sport; 2537221167Sgnn dst_port = uh->uh_dport; 2538221167Sgnn break; 2539221167Sgnn 2540221167Sgnn default: 2541221167Sgnn break; 2542221167Sgnn } 2543221167Sgnn 2544221167Sgnn counter = (ntohs(src_port) + ntohs(dst_port)) & 2545221167Sgnn vpath_selector[queue_len - 1]; 2546221167Sgnn 2547221167Sgnn if (counter >= queue_len) 2548221167Sgnn counter = queue_len - 1; 2549221167Sgnn 2550221167Sgnn return (counter); 2551221167Sgnn} 2552221167Sgnn 2553221167Sgnnstatic inline vxge_hal_vpath_h 2554221167Sgnnvxge_vpath_handle_get(vxge_dev_t *vdev, int i) 2555221167Sgnn{ 2556221167Sgnn return (vdev->vpaths[i].is_open ? vdev->vpaths[i].handle : NULL); 2557221167Sgnn} 2558221167Sgnn 2559221167Sgnnint 2560221167Sgnnvxge_firmware_verify(vxge_dev_t *vdev) 2561221167Sgnn{ 2562221167Sgnn int err = 0; 2563221167Sgnn u64 active_config; 2564221167Sgnn vxge_hal_status_e status = VXGE_HAL_FAIL; 2565221167Sgnn 2566221167Sgnn if (vdev->fw_upgrade) { 2567221167Sgnn status = vxge_firmware_upgrade(vdev); 2568221167Sgnn if (status == VXGE_HAL_OK) { 2569221167Sgnn err = ENXIO; 2570221167Sgnn goto _exit0; 2571221167Sgnn } 2572221167Sgnn } 2573221167Sgnn 2574221167Sgnn if ((vdev->config.function_mode != VXGE_DEFAULT_CONFIG_VALUE) && 2575221167Sgnn (vdev->config.hw_info.function_mode != 2576221167Sgnn (u64) vdev->config.function_mode)) { 2577221167Sgnn 2578221167Sgnn status = vxge_func_mode_set(vdev); 2579221167Sgnn if (status == VXGE_HAL_OK) 2580221167Sgnn err = ENXIO; 2581221167Sgnn } 2582221167Sgnn 2583221167Sgnn /* l2_switch configuration */ 2584221167Sgnn active_config = VXGE_DEFAULT_CONFIG_VALUE; 2585221167Sgnn status = vxge_hal_get_active_config(vdev->devh, 2586221167Sgnn VXGE_HAL_XMAC_NWIF_ActConfig_L2SwitchEnabled, 2587221167Sgnn &active_config); 2588221167Sgnn 2589221167Sgnn if (status == VXGE_HAL_OK) { 2590221167Sgnn vdev->l2_switch = active_config; 2591221167Sgnn if (vdev->config.l2_switch != VXGE_DEFAULT_CONFIG_VALUE) { 2592221167Sgnn if (vdev->config.l2_switch != active_config) { 2593221167Sgnn status = vxge_l2switch_mode_set(vdev); 2594221167Sgnn if (status == VXGE_HAL_OK) 2595221167Sgnn err = ENXIO; 2596221167Sgnn } 2597221167Sgnn } 2598221167Sgnn } 2599221167Sgnn 2600221167Sgnn if (vdev->config.hw_info.ports == VXGE_DUAL_PORT_MODE) { 2601221167Sgnn if (vxge_port_mode_update(vdev) == ENXIO) 2602221167Sgnn err = ENXIO; 2603221167Sgnn } 2604221167Sgnn 2605221167Sgnn_exit0: 2606221167Sgnn if (err == ENXIO) 2607221167Sgnn device_printf(vdev->ndev, "PLEASE POWER CYCLE THE SYSTEM\n"); 2608221167Sgnn 2609221167Sgnn return (err); 2610221167Sgnn} 2611221167Sgnn 2612221167Sgnnvxge_hal_status_e 2613221167Sgnnvxge_firmware_upgrade(vxge_dev_t *vdev) 2614221167Sgnn{ 2615221167Sgnn u8 *fw_buffer; 2616221167Sgnn u32 fw_size; 2617221167Sgnn vxge_hal_device_hw_info_t *hw_info; 2618221167Sgnn vxge_hal_status_e status = VXGE_HAL_OK; 2619221167Sgnn 2620221167Sgnn hw_info = &vdev->config.hw_info; 2621221167Sgnn 2622221167Sgnn fw_size = sizeof(VXGE_FW_ARRAY_NAME); 2623221167Sgnn fw_buffer = (u8 *) VXGE_FW_ARRAY_NAME; 2624221167Sgnn 2625221167Sgnn device_printf(vdev->ndev, "Current firmware version : %s (%s)\n", 2626221167Sgnn hw_info->fw_version.version, hw_info->fw_date.date); 2627221167Sgnn 2628221167Sgnn device_printf(vdev->ndev, "Upgrading firmware to %d.%d.%d\n", 2629221167Sgnn VXGE_MIN_FW_MAJOR_VERSION, VXGE_MIN_FW_MINOR_VERSION, 2630221167Sgnn VXGE_MIN_FW_BUILD_NUMBER); 2631221167Sgnn 2632221167Sgnn /* Call HAL API to upgrade firmware */ 2633221167Sgnn status = vxge_hal_mrpcim_fw_upgrade(vdev->pdev, 2634221167Sgnn (pci_reg_h) vdev->pdev->reg_map[0], 2635221167Sgnn (u8 *) vdev->pdev->bar_info[0], 2636221167Sgnn fw_buffer, fw_size); 2637221167Sgnn 2638221167Sgnn device_printf(vdev->ndev, "firmware upgrade %s\n", 2639221167Sgnn (status == VXGE_HAL_OK) ? "successful" : "failed"); 2640221167Sgnn 2641221167Sgnn return (status); 2642221167Sgnn} 2643221167Sgnn 2644221167Sgnnvxge_hal_status_e 2645221167Sgnnvxge_func_mode_set(vxge_dev_t *vdev) 2646221167Sgnn{ 2647221167Sgnn u64 active_config; 2648221167Sgnn vxge_hal_status_e status = VXGE_HAL_FAIL; 2649221167Sgnn 2650221167Sgnn status = vxge_hal_mrpcim_pcie_func_mode_set(vdev->devh, 2651221167Sgnn vdev->config.function_mode); 2652221167Sgnn device_printf(vdev->ndev, 2653221167Sgnn "function mode change %s\n", 2654221167Sgnn (status == VXGE_HAL_OK) ? "successful" : "failed"); 2655221167Sgnn 2656221167Sgnn if (status == VXGE_HAL_OK) { 2657221167Sgnn vxge_hal_set_fw_api(vdev->devh, 0ULL, 2658221167Sgnn VXGE_HAL_API_FUNC_MODE_COMMIT, 2659221167Sgnn 0, 0ULL, 0ULL); 2660221167Sgnn 2661221167Sgnn vxge_hal_get_active_config(vdev->devh, 2662221167Sgnn VXGE_HAL_XMAC_NWIF_ActConfig_NWPortMode, 2663221167Sgnn &active_config); 2664221167Sgnn 2665221167Sgnn /* 2666221167Sgnn * If in MF + DP mode 2667221167Sgnn * if user changes to SF, change port_mode to single port mode 2668221167Sgnn */ 2669221167Sgnn if (((is_multi_func(vdev->config.hw_info.function_mode)) && 2670221167Sgnn is_single_func(vdev->config.function_mode)) && 2671221167Sgnn (active_config == VXGE_HAL_DP_NP_MODE_DUAL_PORT)) { 2672221167Sgnn vdev->config.port_mode = 2673221167Sgnn VXGE_HAL_DP_NP_MODE_SINGLE_PORT; 2674221167Sgnn 2675221167Sgnn status = vxge_port_mode_set(vdev); 2676221167Sgnn } 2677221167Sgnn } 2678221167Sgnn return (status); 2679221167Sgnn} 2680221167Sgnn 2681221167Sgnnvxge_hal_status_e 2682221167Sgnnvxge_port_mode_set(vxge_dev_t *vdev) 2683221167Sgnn{ 2684221167Sgnn vxge_hal_status_e status = VXGE_HAL_FAIL; 2685221167Sgnn 2686221167Sgnn status = vxge_hal_set_port_mode(vdev->devh, vdev->config.port_mode); 2687221167Sgnn device_printf(vdev->ndev, 2688221167Sgnn "port mode change %s\n", 2689221167Sgnn (status == VXGE_HAL_OK) ? "successful" : "failed"); 2690221167Sgnn 2691221167Sgnn if (status == VXGE_HAL_OK) { 2692221167Sgnn vxge_hal_set_fw_api(vdev->devh, 0ULL, 2693221167Sgnn VXGE_HAL_API_FUNC_MODE_COMMIT, 2694221167Sgnn 0, 0ULL, 0ULL); 2695221167Sgnn 2696221167Sgnn /* Configure vpath_mapping for active-active mode only */ 2697221167Sgnn if (vdev->config.port_mode == VXGE_HAL_DP_NP_MODE_DUAL_PORT) { 2698221167Sgnn 2699221167Sgnn status = vxge_hal_config_vpath_map(vdev->devh, 2700221167Sgnn VXGE_DUAL_PORT_MAP); 2701221167Sgnn 2702221167Sgnn device_printf(vdev->ndev, "dual port map change %s\n", 2703221167Sgnn (status == VXGE_HAL_OK) ? "successful" : "failed"); 2704221167Sgnn } 2705221167Sgnn } 2706221167Sgnn return (status); 2707221167Sgnn} 2708221167Sgnn 2709221167Sgnnint 2710221167Sgnnvxge_port_mode_update(vxge_dev_t *vdev) 2711221167Sgnn{ 2712221167Sgnn int err = 0; 2713221167Sgnn u64 active_config; 2714221167Sgnn vxge_hal_status_e status = VXGE_HAL_FAIL; 2715221167Sgnn 2716221167Sgnn if ((vdev->config.port_mode == VXGE_HAL_DP_NP_MODE_DUAL_PORT) && 2717221167Sgnn is_single_func(vdev->config.hw_info.function_mode)) { 2718221167Sgnn 2719221167Sgnn device_printf(vdev->ndev, 2720221167Sgnn "Adapter in SF mode, dual port mode is not allowed\n"); 2721221167Sgnn err = EPERM; 2722221167Sgnn goto _exit0; 2723221167Sgnn } 2724221167Sgnn 2725221167Sgnn active_config = VXGE_DEFAULT_CONFIG_VALUE; 2726221167Sgnn status = vxge_hal_get_active_config(vdev->devh, 2727221167Sgnn VXGE_HAL_XMAC_NWIF_ActConfig_NWPortMode, 2728221167Sgnn &active_config); 2729221167Sgnn if (status != VXGE_HAL_OK) { 2730221167Sgnn err = EINVAL; 2731221167Sgnn goto _exit0; 2732221167Sgnn } 2733221167Sgnn 2734221167Sgnn vdev->port_mode = active_config; 2735221167Sgnn if (vdev->config.port_mode != VXGE_DEFAULT_CONFIG_VALUE) { 2736221167Sgnn if (vdev->config.port_mode != vdev->port_mode) { 2737221167Sgnn status = vxge_port_mode_set(vdev); 2738221167Sgnn if (status != VXGE_HAL_OK) { 2739221167Sgnn err = EINVAL; 2740221167Sgnn goto _exit0; 2741221167Sgnn } 2742221167Sgnn err = ENXIO; 2743221167Sgnn vdev->port_mode = vdev->config.port_mode; 2744221167Sgnn } 2745221167Sgnn } 2746221167Sgnn 2747221167Sgnn active_config = VXGE_DEFAULT_CONFIG_VALUE; 2748221167Sgnn status = vxge_hal_get_active_config(vdev->devh, 2749221167Sgnn VXGE_HAL_XMAC_NWIF_ActConfig_BehaviourOnFail, 2750221167Sgnn &active_config); 2751221167Sgnn if (status != VXGE_HAL_OK) { 2752221167Sgnn err = EINVAL; 2753221167Sgnn goto _exit0; 2754221167Sgnn } 2755221167Sgnn 2756221167Sgnn vdev->port_failure = active_config; 2757221167Sgnn 2758221167Sgnn /* 2759221167Sgnn * active/active mode : set to NoMove 2760221167Sgnn * active/passive mode: set to Failover-Failback 2761221167Sgnn */ 2762221167Sgnn if (vdev->port_mode == VXGE_HAL_DP_NP_MODE_DUAL_PORT) 2763221167Sgnn vdev->config.port_failure = 2764221167Sgnn VXGE_HAL_XMAC_NWIF_OnFailure_NoMove; 2765221167Sgnn 2766221167Sgnn else if (vdev->port_mode == VXGE_HAL_DP_NP_MODE_ACTIVE_PASSIVE) 2767221167Sgnn vdev->config.port_failure = 2768221167Sgnn VXGE_HAL_XMAC_NWIF_OnFailure_OtherPortBackOnRestore; 2769221167Sgnn 2770221167Sgnn if ((vdev->port_mode != VXGE_HAL_DP_NP_MODE_SINGLE_PORT) && 2771221167Sgnn (vdev->config.port_failure != vdev->port_failure)) { 2772221167Sgnn status = vxge_port_behavior_on_failure_set(vdev); 2773221167Sgnn if (status == VXGE_HAL_OK) 2774221167Sgnn err = ENXIO; 2775221167Sgnn } 2776221167Sgnn 2777221167Sgnn_exit0: 2778221167Sgnn return (err); 2779221167Sgnn} 2780221167Sgnn 2781221167Sgnnvxge_hal_status_e 2782221167Sgnnvxge_port_mode_get(vxge_dev_t *vdev, vxge_port_info_t *port_info) 2783221167Sgnn{ 2784221167Sgnn int err = 0; 2785221167Sgnn u64 active_config; 2786221167Sgnn vxge_hal_status_e status = VXGE_HAL_FAIL; 2787221167Sgnn 2788221167Sgnn active_config = VXGE_DEFAULT_CONFIG_VALUE; 2789221167Sgnn status = vxge_hal_get_active_config(vdev->devh, 2790221167Sgnn VXGE_HAL_XMAC_NWIF_ActConfig_NWPortMode, 2791221167Sgnn &active_config); 2792221167Sgnn 2793221167Sgnn if (status != VXGE_HAL_OK) { 2794221167Sgnn err = ENXIO; 2795221167Sgnn goto _exit0; 2796221167Sgnn } 2797221167Sgnn 2798221167Sgnn port_info->port_mode = active_config; 2799221167Sgnn 2800221167Sgnn active_config = VXGE_DEFAULT_CONFIG_VALUE; 2801221167Sgnn status = vxge_hal_get_active_config(vdev->devh, 2802221167Sgnn VXGE_HAL_XMAC_NWIF_ActConfig_BehaviourOnFail, 2803221167Sgnn &active_config); 2804221167Sgnn if (status != VXGE_HAL_OK) { 2805221167Sgnn err = ENXIO; 2806221167Sgnn goto _exit0; 2807221167Sgnn } 2808221167Sgnn 2809221167Sgnn port_info->port_failure = active_config; 2810221167Sgnn 2811221167Sgnn_exit0: 2812221167Sgnn return (err); 2813221167Sgnn} 2814221167Sgnn 2815221167Sgnnvxge_hal_status_e 2816221167Sgnnvxge_port_behavior_on_failure_set(vxge_dev_t *vdev) 2817221167Sgnn{ 2818221167Sgnn vxge_hal_status_e status = VXGE_HAL_FAIL; 2819221167Sgnn 2820221167Sgnn status = vxge_hal_set_behavior_on_failure(vdev->devh, 2821221167Sgnn vdev->config.port_failure); 2822221167Sgnn 2823221167Sgnn device_printf(vdev->ndev, 2824221167Sgnn "port behaviour on failure change %s\n", 2825221167Sgnn (status == VXGE_HAL_OK) ? "successful" : "failed"); 2826221167Sgnn 2827221167Sgnn if (status == VXGE_HAL_OK) 2828221167Sgnn vxge_hal_set_fw_api(vdev->devh, 0ULL, 2829221167Sgnn VXGE_HAL_API_FUNC_MODE_COMMIT, 2830221167Sgnn 0, 0ULL, 0ULL); 2831221167Sgnn 2832221167Sgnn return (status); 2833221167Sgnn} 2834221167Sgnn 2835221167Sgnnvoid 2836221167Sgnnvxge_active_port_update(vxge_dev_t *vdev) 2837221167Sgnn{ 2838221167Sgnn u64 active_config; 2839221167Sgnn vxge_hal_status_e status = VXGE_HAL_FAIL; 2840221167Sgnn 2841221167Sgnn active_config = VXGE_DEFAULT_CONFIG_VALUE; 2842221167Sgnn status = vxge_hal_get_active_config(vdev->devh, 2843221167Sgnn VXGE_HAL_XMAC_NWIF_ActConfig_ActivePort, 2844221167Sgnn &active_config); 2845221167Sgnn 2846221167Sgnn if (status == VXGE_HAL_OK) 2847221167Sgnn vdev->active_port = active_config; 2848221167Sgnn} 2849221167Sgnn 2850221167Sgnnvxge_hal_status_e 2851221167Sgnnvxge_l2switch_mode_set(vxge_dev_t *vdev) 2852221167Sgnn{ 2853221167Sgnn vxge_hal_status_e status = VXGE_HAL_FAIL; 2854221167Sgnn 2855221167Sgnn status = vxge_hal_set_l2switch_mode(vdev->devh, 2856221167Sgnn vdev->config.l2_switch); 2857221167Sgnn 2858221167Sgnn device_printf(vdev->ndev, "L2 switch %s\n", 2859221167Sgnn (status == VXGE_HAL_OK) ? 2860221167Sgnn (vdev->config.l2_switch) ? "enable" : "disable" : 2861221167Sgnn "change failed"); 2862221167Sgnn 2863221167Sgnn if (status == VXGE_HAL_OK) 2864221167Sgnn vxge_hal_set_fw_api(vdev->devh, 0ULL, 2865221167Sgnn VXGE_HAL_API_FUNC_MODE_COMMIT, 2866221167Sgnn 0, 0ULL, 0ULL); 2867221167Sgnn 2868221167Sgnn return (status); 2869221167Sgnn} 2870221167Sgnn 2871221167Sgnn/* 2872221167Sgnn * vxge_promisc_set 2873221167Sgnn * Enable Promiscuous Mode 2874221167Sgnn */ 2875221167Sgnnvoid 2876221167Sgnnvxge_promisc_set(vxge_dev_t *vdev) 2877221167Sgnn{ 2878221167Sgnn int i; 2879221167Sgnn ifnet_t ifp; 2880221167Sgnn vxge_hal_vpath_h vpath_handle; 2881221167Sgnn 2882221167Sgnn if (!vdev->is_initialized) 2883221167Sgnn return; 2884221167Sgnn 2885221167Sgnn ifp = vdev->ifp; 2886221167Sgnn 2887221167Sgnn for (i = 0; i < vdev->no_of_vpath; i++) { 2888221167Sgnn vpath_handle = vxge_vpath_handle_get(vdev, i); 2889221167Sgnn if (!vpath_handle) 2890221167Sgnn continue; 2891221167Sgnn 2892221167Sgnn if (ifp->if_flags & IFF_PROMISC) 2893221167Sgnn vxge_hal_vpath_promisc_enable(vpath_handle); 2894221167Sgnn else 2895221167Sgnn vxge_hal_vpath_promisc_disable(vpath_handle); 2896221167Sgnn } 2897221167Sgnn} 2898221167Sgnn 2899221167Sgnn/* 2900221167Sgnn * vxge_change_mtu 2901221167Sgnn * Change interface MTU to a requested valid size 2902221167Sgnn */ 2903221167Sgnnint 2904221167Sgnnvxge_change_mtu(vxge_dev_t *vdev, unsigned long new_mtu) 2905221167Sgnn{ 2906221167Sgnn int err = EINVAL; 2907221167Sgnn 2908221167Sgnn if ((new_mtu < VXGE_HAL_MIN_MTU) || (new_mtu > VXGE_HAL_MAX_MTU)) 2909221167Sgnn goto _exit0; 2910221167Sgnn 2911221167Sgnn (vdev->ifp)->if_mtu = new_mtu; 2912221167Sgnn device_printf(vdev->ndev, "MTU changed to %ld\n", (vdev->ifp)->if_mtu); 2913221167Sgnn 2914221167Sgnn if (vdev->is_initialized) { 2915221167Sgnn if_down(vdev->ifp); 2916221167Sgnn vxge_reset(vdev); 2917221167Sgnn if_up(vdev->ifp); 2918221167Sgnn } 2919221167Sgnn err = 0; 2920221167Sgnn 2921221167Sgnn_exit0: 2922221167Sgnn return (err); 2923221167Sgnn} 2924221167Sgnn 2925221167Sgnn/* 2926221167Sgnn * Creates DMA tags for both Tx and Rx 2927221167Sgnn */ 2928221167Sgnnint 2929221167Sgnnvxge_dma_tags_create(vxge_vpath_t *vpath) 2930221167Sgnn{ 2931221167Sgnn int err = 0; 2932221167Sgnn bus_size_t max_size, boundary; 2933221167Sgnn vxge_dev_t *vdev = vpath->vdev; 2934221167Sgnn ifnet_t ifp = vdev->ifp; 2935221167Sgnn 2936221167Sgnn max_size = ifp->if_mtu + 2937221167Sgnn VXGE_HAL_MAC_HEADER_MAX_SIZE + 2938221167Sgnn VXGE_HAL_HEADER_ETHERNET_II_802_3_ALIGN; 2939221167Sgnn 2940221167Sgnn VXGE_BUFFER_ALIGN(max_size, 128) 2941221167Sgnn if (max_size <= MCLBYTES) 2942221167Sgnn vdev->rx_mbuf_sz = MCLBYTES; 2943221167Sgnn else 2944221167Sgnn vdev->rx_mbuf_sz = 2945221167Sgnn (max_size > MJUMPAGESIZE) ? MJUM9BYTES : MJUMPAGESIZE; 2946221167Sgnn 2947221167Sgnn boundary = (max_size > PAGE_SIZE) ? 0 : PAGE_SIZE; 2948221167Sgnn 2949221167Sgnn /* DMA tag for Tx */ 2950221167Sgnn err = bus_dma_tag_create( 2951221167Sgnn bus_get_dma_tag(vdev->ndev), 2952221167Sgnn 1, 2953221167Sgnn PAGE_SIZE, 2954221167Sgnn BUS_SPACE_MAXADDR, 2955221167Sgnn BUS_SPACE_MAXADDR, 2956221167Sgnn NULL, 2957221167Sgnn NULL, 2958221167Sgnn VXGE_TSO_SIZE, 2959221167Sgnn VXGE_MAX_SEGS, 2960221167Sgnn PAGE_SIZE, 2961221167Sgnn BUS_DMA_ALLOCNOW, 2962221167Sgnn NULL, 2963221167Sgnn NULL, 2964221167Sgnn &(vpath->dma_tag_tx)); 2965221167Sgnn if (err != 0) 2966221167Sgnn goto _exit0; 2967221167Sgnn 2968221167Sgnn /* DMA tag for Rx */ 2969221167Sgnn err = bus_dma_tag_create( 2970221167Sgnn bus_get_dma_tag(vdev->ndev), 2971221167Sgnn 1, 2972221167Sgnn boundary, 2973221167Sgnn BUS_SPACE_MAXADDR, 2974221167Sgnn BUS_SPACE_MAXADDR, 2975221167Sgnn NULL, 2976221167Sgnn NULL, 2977221167Sgnn vdev->rx_mbuf_sz, 2978221167Sgnn 1, 2979221167Sgnn vdev->rx_mbuf_sz, 2980221167Sgnn BUS_DMA_ALLOCNOW, 2981221167Sgnn NULL, 2982221167Sgnn NULL, 2983221167Sgnn &(vpath->dma_tag_rx)); 2984221167Sgnn if (err != 0) 2985221167Sgnn goto _exit1; 2986221167Sgnn 2987221167Sgnn /* Create DMA map for this descriptor */ 2988221167Sgnn err = bus_dmamap_create(vpath->dma_tag_rx, BUS_DMA_NOWAIT, 2989221167Sgnn &vpath->extra_dma_map); 2990221167Sgnn if (err == 0) 2991221167Sgnn goto _exit0; 2992221167Sgnn 2993221167Sgnn bus_dma_tag_destroy(vpath->dma_tag_rx); 2994221167Sgnn 2995221167Sgnn_exit1: 2996221167Sgnn bus_dma_tag_destroy(vpath->dma_tag_tx); 2997221167Sgnn 2998221167Sgnn_exit0: 2999221167Sgnn return (err); 3000221167Sgnn} 3001221167Sgnn 3002221167Sgnnstatic inline int 3003221167Sgnnvxge_dma_mbuf_coalesce(bus_dma_tag_t dma_tag_tx, bus_dmamap_t dma_map, 3004221167Sgnn mbuf_t * m_headp, bus_dma_segment_t * dma_buffers, 3005221167Sgnn int *num_segs) 3006221167Sgnn{ 3007221167Sgnn int err = 0; 3008221167Sgnn mbuf_t mbuf_pkt = NULL; 3009221167Sgnn 3010221167Sgnnretry: 3011221167Sgnn err = bus_dmamap_load_mbuf_sg(dma_tag_tx, dma_map, *m_headp, 3012221167Sgnn dma_buffers, num_segs, BUS_DMA_NOWAIT); 3013221167Sgnn if (err == EFBIG) { 3014221167Sgnn /* try to defrag, too many segments */ 3015248078Smarius mbuf_pkt = m_defrag(*m_headp, M_NOWAIT); 3016221167Sgnn if (mbuf_pkt == NULL) { 3017221167Sgnn err = ENOBUFS; 3018221167Sgnn goto _exit0; 3019221167Sgnn } 3020221167Sgnn *m_headp = mbuf_pkt; 3021221167Sgnn goto retry; 3022221167Sgnn } 3023221167Sgnn 3024221167Sgnn_exit0: 3025221167Sgnn return (err); 3026221167Sgnn} 3027221167Sgnn 3028221167Sgnnint 3029221167Sgnnvxge_device_hw_info_get(vxge_dev_t *vdev) 3030221167Sgnn{ 3031221167Sgnn int i, err = ENXIO; 3032221167Sgnn u64 vpath_mask = 0; 3033221167Sgnn u32 max_supported_vpath = 0; 3034221167Sgnn u32 fw_ver_maj_min; 3035221167Sgnn vxge_firmware_upgrade_e fw_option; 3036221167Sgnn 3037221167Sgnn vxge_hal_status_e status = VXGE_HAL_OK; 3038221167Sgnn vxge_hal_device_hw_info_t *hw_info; 3039221167Sgnn 3040221167Sgnn status = vxge_hal_device_hw_info_get(vdev->pdev, 3041221167Sgnn (pci_reg_h) vdev->pdev->reg_map[0], 3042221167Sgnn (u8 *) vdev->pdev->bar_info[0], 3043221167Sgnn &vdev->config.hw_info); 3044221167Sgnn 3045221167Sgnn if (status != VXGE_HAL_OK) 3046221167Sgnn goto _exit0; 3047221167Sgnn 3048221167Sgnn hw_info = &vdev->config.hw_info; 3049221167Sgnn 3050221167Sgnn vpath_mask = hw_info->vpath_mask; 3051221167Sgnn if (vpath_mask == 0) { 3052221167Sgnn device_printf(vdev->ndev, "No vpaths available in device\n"); 3053221167Sgnn goto _exit0; 3054221167Sgnn } 3055221167Sgnn 3056221167Sgnn fw_option = vdev->config.fw_option; 3057221167Sgnn 3058221167Sgnn /* Check how many vpaths are available */ 3059221167Sgnn for (i = 0; i < VXGE_HAL_MAX_VIRTUAL_PATHS; i++) { 3060221167Sgnn if (!((vpath_mask) & mBIT(i))) 3061221167Sgnn continue; 3062221167Sgnn max_supported_vpath++; 3063221167Sgnn } 3064221167Sgnn 3065221167Sgnn vdev->max_supported_vpath = max_supported_vpath; 3066221167Sgnn status = vxge_hal_device_is_privileged(hw_info->host_type, 3067221167Sgnn hw_info->func_id); 3068221167Sgnn vdev->is_privilaged = (status == VXGE_HAL_OK) ? TRUE : FALSE; 3069221167Sgnn 3070221167Sgnn vdev->hw_fw_version = VXGE_FW_VERSION( 3071221167Sgnn hw_info->fw_version.major, 3072221167Sgnn hw_info->fw_version.minor, 3073221167Sgnn hw_info->fw_version.build); 3074221167Sgnn 3075221167Sgnn fw_ver_maj_min = 3076221167Sgnn VXGE_FW_MAJ_MIN_VERSION(hw_info->fw_version.major, 3077221167Sgnn hw_info->fw_version.minor); 3078221167Sgnn 3079221167Sgnn if ((fw_option >= VXGE_FW_UPGRADE_FORCE) || 3080221167Sgnn (vdev->hw_fw_version != VXGE_DRV_FW_VERSION)) { 3081221167Sgnn 3082221167Sgnn /* For fw_ver 1.8.1 and above ignore build number. */ 3083221167Sgnn if ((fw_option == VXGE_FW_UPGRADE_ALL) && 3084221167Sgnn ((vdev->hw_fw_version >= VXGE_FW_VERSION(1, 8, 1)) && 3085221167Sgnn (fw_ver_maj_min == VXGE_DRV_FW_MAJ_MIN_VERSION))) { 3086221167Sgnn goto _exit1; 3087221167Sgnn } 3088221167Sgnn 3089221167Sgnn if (vdev->hw_fw_version < VXGE_BASE_FW_VERSION) { 3090221167Sgnn device_printf(vdev->ndev, 3091221167Sgnn "Upgrade driver through vxge_update, " 3092221167Sgnn "Unable to load the driver.\n"); 3093221167Sgnn goto _exit0; 3094221167Sgnn } 3095221167Sgnn vdev->fw_upgrade = TRUE; 3096221167Sgnn } 3097221167Sgnn 3098221167Sgnn_exit1: 3099221167Sgnn err = 0; 3100221167Sgnn 3101221167Sgnn_exit0: 3102221167Sgnn return (err); 3103221167Sgnn} 3104221167Sgnn 3105221167Sgnn/* 3106221167Sgnn * vxge_device_hw_info_print 3107221167Sgnn * Print device and driver information 3108221167Sgnn */ 3109221167Sgnnvoid 3110221167Sgnnvxge_device_hw_info_print(vxge_dev_t *vdev) 3111221167Sgnn{ 3112221167Sgnn u32 i; 3113221167Sgnn device_t ndev; 3114221167Sgnn struct sysctl_ctx_list *ctx; 3115221167Sgnn struct sysctl_oid_list *children; 3116221167Sgnn char pmd_type[2][VXGE_PMD_INFO_LEN]; 3117221167Sgnn 3118221167Sgnn vxge_hal_device_t *hldev; 3119221167Sgnn vxge_hal_device_hw_info_t *hw_info; 3120221167Sgnn vxge_hal_device_pmd_info_t *pmd_port; 3121221167Sgnn 3122221167Sgnn hldev = vdev->devh; 3123221167Sgnn ndev = vdev->ndev; 3124221167Sgnn 3125221167Sgnn ctx = device_get_sysctl_ctx(ndev); 3126221167Sgnn children = SYSCTL_CHILDREN(device_get_sysctl_tree(ndev)); 3127221167Sgnn 3128221167Sgnn hw_info = &(vdev->config.hw_info); 3129221167Sgnn 3130221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_DRV_VERSION], 3131221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_DRV_VERSION]), 3132221167Sgnn "%d.%d.%d.%d", XGELL_VERSION_MAJOR, XGELL_VERSION_MINOR, 3133221167Sgnn XGELL_VERSION_FIX, XGELL_VERSION_BUILD); 3134221167Sgnn 3135221167Sgnn /* Print PCI-e bus type/speed/width info */ 3136221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_PCIE_INFO], 3137221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_PCIE_INFO]), 3138221167Sgnn "x%d", hldev->link_width); 3139221167Sgnn 3140221167Sgnn if (hldev->link_width <= VXGE_HAL_PCI_E_LINK_WIDTH_X4) 3141221167Sgnn device_printf(ndev, "For optimal performance a x8 " 3142221167Sgnn "PCI-Express slot is required.\n"); 3143221167Sgnn 3144221167Sgnn vxge_null_terminate((char *) hw_info->serial_number, 3145221167Sgnn sizeof(hw_info->serial_number)); 3146221167Sgnn 3147221167Sgnn vxge_null_terminate((char *) hw_info->part_number, 3148221167Sgnn sizeof(hw_info->part_number)); 3149221167Sgnn 3150221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_SERIAL_NO], 3151221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_SERIAL_NO]), 3152221167Sgnn "%s", hw_info->serial_number); 3153221167Sgnn 3154221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_PART_NO], 3155221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_PART_NO]), 3156221167Sgnn "%s", hw_info->part_number); 3157221167Sgnn 3158221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_FW_VERSION], 3159221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_FW_VERSION]), 3160221167Sgnn "%s", hw_info->fw_version.version); 3161221167Sgnn 3162221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_FW_DATE], 3163221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_FW_DATE]), 3164221167Sgnn "%s", hw_info->fw_date.date); 3165221167Sgnn 3166221167Sgnn pmd_port = &(hw_info->pmd_port0); 3167221167Sgnn for (i = 0; i < hw_info->ports; i++) { 3168221167Sgnn 3169221167Sgnn vxge_pmd_port_type_get(vdev, pmd_port->type, 3170221167Sgnn pmd_type[i], sizeof(pmd_type[i])); 3171221167Sgnn 3172221167Sgnn strncpy(vdev->config.nic_attr[VXGE_PRINT_PMD_PORTS_0 + i], 3173221167Sgnn "vendor=??, sn=??, pn=??, type=??", 3174221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_PMD_PORTS_0 + i])); 3175221167Sgnn 3176221167Sgnn vxge_null_terminate(pmd_port->vendor, sizeof(pmd_port->vendor)); 3177221167Sgnn if (strlen(pmd_port->vendor) == 0) { 3178221167Sgnn pmd_port = &(hw_info->pmd_port1); 3179221167Sgnn continue; 3180221167Sgnn } 3181221167Sgnn 3182221167Sgnn vxge_null_terminate(pmd_port->ser_num, 3183221167Sgnn sizeof(pmd_port->ser_num)); 3184221167Sgnn 3185221167Sgnn vxge_null_terminate(pmd_port->part_num, 3186221167Sgnn sizeof(pmd_port->part_num)); 3187221167Sgnn 3188221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_PMD_PORTS_0 + i], 3189221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_PMD_PORTS_0 + i]), 3190221167Sgnn "vendor=%s, sn=%s, pn=%s, type=%s", 3191221167Sgnn pmd_port->vendor, pmd_port->ser_num, 3192221167Sgnn pmd_port->part_num, pmd_type[i]); 3193221167Sgnn 3194221167Sgnn pmd_port = &(hw_info->pmd_port1); 3195221167Sgnn } 3196221167Sgnn 3197221167Sgnn switch (hw_info->function_mode) { 3198221167Sgnn case VXGE_HAL_PCIE_FUNC_MODE_SF1_VP17: 3199221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_FUNC_MODE], 3200221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_FUNC_MODE]), 3201221167Sgnn "%s %d %s", "Single Function - 1 function(s)", 3202221167Sgnn vdev->max_supported_vpath, "VPath(s)/function"); 3203221167Sgnn break; 3204221167Sgnn 3205221167Sgnn case VXGE_HAL_PCIE_FUNC_MODE_MF2_VP8: 3206221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_FUNC_MODE], 3207221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_FUNC_MODE]), 3208221167Sgnn "%s %d %s", "Multi Function - 2 function(s)", 3209221167Sgnn vdev->max_supported_vpath, "VPath(s)/function"); 3210221167Sgnn break; 3211221167Sgnn 3212221167Sgnn case VXGE_HAL_PCIE_FUNC_MODE_MF4_VP4: 3213221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_FUNC_MODE], 3214221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_FUNC_MODE]), 3215221167Sgnn "%s %d %s", "Multi Function - 4 function(s)", 3216221167Sgnn vdev->max_supported_vpath, "VPath(s)/function"); 3217221167Sgnn break; 3218221167Sgnn 3219221167Sgnn case VXGE_HAL_PCIE_FUNC_MODE_MF8_VP2: 3220221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_FUNC_MODE], 3221221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_FUNC_MODE]), 3222221167Sgnn "%s %d %s", "Multi Function - 8 function(s)", 3223221167Sgnn vdev->max_supported_vpath, "VPath(s)/function"); 3224221167Sgnn break; 3225221167Sgnn 3226221167Sgnn case VXGE_HAL_PCIE_FUNC_MODE_MF8P_VP2: 3227221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_FUNC_MODE], 3228221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_FUNC_MODE]), 3229221167Sgnn "%s %d %s", "Multi Function (DirectIO) - 8 function(s)", 3230221167Sgnn vdev->max_supported_vpath, "VPath(s)/function"); 3231221167Sgnn break; 3232221167Sgnn } 3233221167Sgnn 3234221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_INTR_MODE], 3235221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_INTR_MODE]), 3236221167Sgnn "%s", ((vdev->config.intr_mode == VXGE_HAL_INTR_MODE_MSIX) ? 3237221167Sgnn "MSI-X" : "INTA")); 3238221167Sgnn 3239221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_VPATH_COUNT], 3240221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_VPATH_COUNT]), 3241221167Sgnn "%d", vdev->no_of_vpath); 3242221167Sgnn 3243221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_MTU_SIZE], 3244221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_MTU_SIZE]), 3245221167Sgnn "%lu", vdev->ifp->if_mtu); 3246221167Sgnn 3247221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_LRO_MODE], 3248221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_LRO_MODE]), 3249221167Sgnn "%s", ((vdev->config.lro_enable) ? "Enabled" : "Disabled")); 3250221167Sgnn 3251221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_RTH_MODE], 3252221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_RTH_MODE]), 3253221167Sgnn "%s", ((vdev->config.rth_enable) ? "Enabled" : "Disabled")); 3254221167Sgnn 3255221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_TSO_MODE], 3256221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_TSO_MODE]), 3257221167Sgnn "%s", ((vdev->ifp->if_capenable & IFCAP_TSO4) ? 3258221167Sgnn "Enabled" : "Disabled")); 3259221167Sgnn 3260221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_ADAPTER_TYPE], 3261221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_ADAPTER_TYPE]), 3262221167Sgnn "%s", ((hw_info->ports == 1) ? "Single Port" : "Dual Port")); 3263221167Sgnn 3264221167Sgnn if (vdev->is_privilaged) { 3265221167Sgnn 3266221167Sgnn if (hw_info->ports > 1) { 3267221167Sgnn 3268221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_PORT_MODE], 3269221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_PORT_MODE]), 3270221167Sgnn "%s", vxge_port_mode[vdev->port_mode]); 3271221167Sgnn 3272221167Sgnn if (vdev->port_mode != VXGE_HAL_DP_NP_MODE_SINGLE_PORT) 3273221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_PORT_FAILURE], 3274221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_PORT_FAILURE]), 3275221167Sgnn "%s", vxge_port_failure[vdev->port_failure]); 3276221167Sgnn 3277221167Sgnn vxge_active_port_update(vdev); 3278221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_ACTIVE_PORT], 3279221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_ACTIVE_PORT]), 3280221167Sgnn "%lld", vdev->active_port); 3281221167Sgnn } 3282221167Sgnn 3283221167Sgnn if (!is_single_func(hw_info->function_mode)) { 3284221167Sgnn snprintf(vdev->config.nic_attr[VXGE_PRINT_L2SWITCH_MODE], 3285221167Sgnn sizeof(vdev->config.nic_attr[VXGE_PRINT_L2SWITCH_MODE]), 3286221167Sgnn "%s", ((vdev->l2_switch) ? "Enabled" : "Disabled")); 3287221167Sgnn } 3288221167Sgnn } 3289221167Sgnn 3290221167Sgnn device_printf(ndev, "Driver version\t: %s\n", 3291221167Sgnn vdev->config.nic_attr[VXGE_PRINT_DRV_VERSION]); 3292221167Sgnn 3293221167Sgnn device_printf(ndev, "Serial number\t: %s\n", 3294221167Sgnn vdev->config.nic_attr[VXGE_PRINT_SERIAL_NO]); 3295221167Sgnn 3296221167Sgnn device_printf(ndev, "Part number\t: %s\n", 3297221167Sgnn vdev->config.nic_attr[VXGE_PRINT_PART_NO]); 3298221167Sgnn 3299221167Sgnn device_printf(ndev, "Firmware version\t: %s\n", 3300221167Sgnn vdev->config.nic_attr[VXGE_PRINT_FW_VERSION]); 3301221167Sgnn 3302221167Sgnn device_printf(ndev, "Firmware date\t: %s\n", 3303221167Sgnn vdev->config.nic_attr[VXGE_PRINT_FW_DATE]); 3304221167Sgnn 3305221167Sgnn device_printf(ndev, "Link width\t: %s\n", 3306221167Sgnn vdev->config.nic_attr[VXGE_PRINT_PCIE_INFO]); 3307221167Sgnn 3308221167Sgnn if (vdev->is_privilaged) { 3309221167Sgnn device_printf(ndev, "Function mode\t: %s\n", 3310221167Sgnn vdev->config.nic_attr[VXGE_PRINT_FUNC_MODE]); 3311221167Sgnn } 3312221167Sgnn 3313221167Sgnn device_printf(ndev, "Interrupt type\t: %s\n", 3314221167Sgnn vdev->config.nic_attr[VXGE_PRINT_INTR_MODE]); 3315221167Sgnn 3316221167Sgnn device_printf(ndev, "VPath(s) opened\t: %s\n", 3317221167Sgnn vdev->config.nic_attr[VXGE_PRINT_VPATH_COUNT]); 3318221167Sgnn 3319221167Sgnn device_printf(ndev, "Adapter Type\t: %s\n", 3320221167Sgnn vdev->config.nic_attr[VXGE_PRINT_ADAPTER_TYPE]); 3321221167Sgnn 3322221167Sgnn device_printf(ndev, "PMD Port 0\t: %s\n", 3323221167Sgnn vdev->config.nic_attr[VXGE_PRINT_PMD_PORTS_0]); 3324221167Sgnn 3325221167Sgnn if (hw_info->ports > 1) { 3326221167Sgnn device_printf(ndev, "PMD Port 1\t: %s\n", 3327221167Sgnn vdev->config.nic_attr[VXGE_PRINT_PMD_PORTS_1]); 3328221167Sgnn 3329221167Sgnn if (vdev->is_privilaged) { 3330221167Sgnn device_printf(ndev, "Port Mode\t: %s\n", 3331221167Sgnn vdev->config.nic_attr[VXGE_PRINT_PORT_MODE]); 3332221167Sgnn 3333221167Sgnn if (vdev->port_mode != VXGE_HAL_DP_NP_MODE_SINGLE_PORT) 3334221167Sgnn device_printf(ndev, "Port Failure\t: %s\n", 3335221167Sgnn vdev->config.nic_attr[VXGE_PRINT_PORT_FAILURE]); 3336221167Sgnn 3337221167Sgnn device_printf(vdev->ndev, "Active Port\t: %s\n", 3338221167Sgnn vdev->config.nic_attr[VXGE_PRINT_ACTIVE_PORT]); 3339221167Sgnn } 3340221167Sgnn } 3341221167Sgnn 3342221167Sgnn if (vdev->is_privilaged && !is_single_func(hw_info->function_mode)) { 3343221167Sgnn device_printf(vdev->ndev, "L2 Switch\t: %s\n", 3344221167Sgnn vdev->config.nic_attr[VXGE_PRINT_L2SWITCH_MODE]); 3345221167Sgnn } 3346221167Sgnn 3347221167Sgnn device_printf(ndev, "MTU is %s\n", 3348221167Sgnn vdev->config.nic_attr[VXGE_PRINT_MTU_SIZE]); 3349221167Sgnn 3350221167Sgnn device_printf(ndev, "LRO %s\n", 3351221167Sgnn vdev->config.nic_attr[VXGE_PRINT_LRO_MODE]); 3352221167Sgnn 3353221167Sgnn device_printf(ndev, "RTH %s\n", 3354221167Sgnn vdev->config.nic_attr[VXGE_PRINT_RTH_MODE]); 3355221167Sgnn 3356221167Sgnn device_printf(ndev, "TSO %s\n", 3357221167Sgnn vdev->config.nic_attr[VXGE_PRINT_TSO_MODE]); 3358221167Sgnn 3359221167Sgnn SYSCTL_ADD_STRING(ctx, children, 3360221167Sgnn OID_AUTO, "Driver version", CTLFLAG_RD, 3361221167Sgnn &vdev->config.nic_attr[VXGE_PRINT_DRV_VERSION], 3362221167Sgnn 0, "Driver version"); 3363221167Sgnn 3364221167Sgnn SYSCTL_ADD_STRING(ctx, children, 3365221167Sgnn OID_AUTO, "Serial number", CTLFLAG_RD, 3366221167Sgnn &vdev->config.nic_attr[VXGE_PRINT_SERIAL_NO], 3367221167Sgnn 0, "Serial number"); 3368221167Sgnn 3369221167Sgnn SYSCTL_ADD_STRING(ctx, children, 3370221167Sgnn OID_AUTO, "Part number", CTLFLAG_RD, 3371221167Sgnn &vdev->config.nic_attr[VXGE_PRINT_PART_NO], 3372221167Sgnn 0, "Part number"); 3373221167Sgnn 3374221167Sgnn SYSCTL_ADD_STRING(ctx, children, 3375221167Sgnn OID_AUTO, "Firmware version", CTLFLAG_RD, 3376221167Sgnn &vdev->config.nic_attr[VXGE_PRINT_FW_VERSION], 3377221167Sgnn 0, "Firmware version"); 3378221167Sgnn 3379221167Sgnn SYSCTL_ADD_STRING(ctx, children, 3380221167Sgnn OID_AUTO, "Firmware date", CTLFLAG_RD, 3381221167Sgnn &vdev->config.nic_attr[VXGE_PRINT_FW_DATE], 3382221167Sgnn 0, "Firmware date"); 3383221167Sgnn 3384221167Sgnn SYSCTL_ADD_STRING(ctx, children, 3385221167Sgnn OID_AUTO, "Link width", CTLFLAG_RD, 3386221167Sgnn &vdev->config.nic_attr[VXGE_PRINT_PCIE_INFO], 3387221167Sgnn 0, "Link width"); 3388221167Sgnn 3389221167Sgnn if (vdev->is_privilaged) { 3390221167Sgnn SYSCTL_ADD_STRING(ctx, children, 3391221167Sgnn OID_AUTO, "Function mode", CTLFLAG_RD, 3392221167Sgnn &vdev->config.nic_attr[VXGE_PRINT_FUNC_MODE], 3393221167Sgnn 0, "Function mode"); 3394221167Sgnn } 3395221167Sgnn 3396221167Sgnn SYSCTL_ADD_STRING(ctx, children, 3397221167Sgnn OID_AUTO, "Interrupt type", CTLFLAG_RD, 3398221167Sgnn &vdev->config.nic_attr[VXGE_PRINT_INTR_MODE], 3399221167Sgnn 0, "Interrupt type"); 3400221167Sgnn 3401221167Sgnn SYSCTL_ADD_STRING(ctx, children, 3402221167Sgnn OID_AUTO, "VPath(s) opened", CTLFLAG_RD, 3403221167Sgnn &vdev->config.nic_attr[VXGE_PRINT_VPATH_COUNT], 3404221167Sgnn 0, "VPath(s) opened"); 3405221167Sgnn 3406221167Sgnn SYSCTL_ADD_STRING(ctx, children, 3407221167Sgnn OID_AUTO, "Adapter Type", CTLFLAG_RD, 3408221167Sgnn &vdev->config.nic_attr[VXGE_PRINT_ADAPTER_TYPE], 3409221167Sgnn 0, "Adapter Type"); 3410221167Sgnn 3411221167Sgnn SYSCTL_ADD_STRING(ctx, children, 3412221167Sgnn OID_AUTO, "pmd port 0", CTLFLAG_RD, 3413221167Sgnn &vdev->config.nic_attr[VXGE_PRINT_PMD_PORTS_0], 3414221167Sgnn 0, "pmd port"); 3415221167Sgnn 3416221167Sgnn if (hw_info->ports > 1) { 3417221167Sgnn 3418221167Sgnn SYSCTL_ADD_STRING(ctx, children, 3419221167Sgnn OID_AUTO, "pmd port 1", CTLFLAG_RD, 3420221167Sgnn &vdev->config.nic_attr[VXGE_PRINT_PMD_PORTS_1], 3421221167Sgnn 0, "pmd port"); 3422221167Sgnn 3423221167Sgnn if (vdev->is_privilaged) { 3424221167Sgnn SYSCTL_ADD_STRING(ctx, children, 3425221167Sgnn OID_AUTO, "Port Mode", CTLFLAG_RD, 3426221167Sgnn &vdev->config.nic_attr[VXGE_PRINT_PORT_MODE], 3427221167Sgnn 0, "Port Mode"); 3428221167Sgnn 3429221167Sgnn if (vdev->port_mode != VXGE_HAL_DP_NP_MODE_SINGLE_PORT) 3430221167Sgnn SYSCTL_ADD_STRING(ctx, children, 3431221167Sgnn OID_AUTO, "Port Failure", CTLFLAG_RD, 3432221167Sgnn &vdev->config.nic_attr[VXGE_PRINT_PORT_FAILURE], 3433221167Sgnn 0, "Port Failure"); 3434221167Sgnn 3435221167Sgnn SYSCTL_ADD_STRING(ctx, children, 3436221167Sgnn OID_AUTO, "L2 Switch", CTLFLAG_RD, 3437221167Sgnn &vdev->config.nic_attr[VXGE_PRINT_L2SWITCH_MODE], 3438221167Sgnn 0, "L2 Switch"); 3439221167Sgnn } 3440221167Sgnn } 3441221167Sgnn 3442221167Sgnn SYSCTL_ADD_STRING(ctx, children, 3443221167Sgnn OID_AUTO, "LRO mode", CTLFLAG_RD, 3444221167Sgnn &vdev->config.nic_attr[VXGE_PRINT_LRO_MODE], 3445221167Sgnn 0, "LRO mode"); 3446221167Sgnn 3447221167Sgnn SYSCTL_ADD_STRING(ctx, children, 3448221167Sgnn OID_AUTO, "RTH mode", CTLFLAG_RD, 3449221167Sgnn &vdev->config.nic_attr[VXGE_PRINT_RTH_MODE], 3450221167Sgnn 0, "RTH mode"); 3451221167Sgnn 3452221167Sgnn SYSCTL_ADD_STRING(ctx, children, 3453221167Sgnn OID_AUTO, "TSO mode", CTLFLAG_RD, 3454221167Sgnn &vdev->config.nic_attr[VXGE_PRINT_TSO_MODE], 3455221167Sgnn 0, "TSO mode"); 3456221167Sgnn} 3457221167Sgnn 3458221167Sgnnvoid 3459221167Sgnnvxge_pmd_port_type_get(vxge_dev_t *vdev, u32 port_type, 3460221167Sgnn char *ifm_name, u8 ifm_len) 3461221167Sgnn{ 3462221167Sgnn 3463221167Sgnn vdev->ifm_optics = IFM_UNKNOWN; 3464221167Sgnn 3465221167Sgnn switch (port_type) { 3466221167Sgnn case VXGE_HAL_DEVICE_PMD_TYPE_10G_SR: 3467221167Sgnn vdev->ifm_optics = IFM_10G_SR; 3468221167Sgnn strlcpy(ifm_name, "10GbE SR", ifm_len); 3469221167Sgnn break; 3470221167Sgnn 3471221167Sgnn case VXGE_HAL_DEVICE_PMD_TYPE_10G_LR: 3472221167Sgnn vdev->ifm_optics = IFM_10G_LR; 3473221167Sgnn strlcpy(ifm_name, "10GbE LR", ifm_len); 3474221167Sgnn break; 3475221167Sgnn 3476221167Sgnn case VXGE_HAL_DEVICE_PMD_TYPE_10G_LRM: 3477221167Sgnn vdev->ifm_optics = IFM_10G_LRM; 3478221167Sgnn strlcpy(ifm_name, "10GbE LRM", ifm_len); 3479221167Sgnn break; 3480221167Sgnn 3481221167Sgnn case VXGE_HAL_DEVICE_PMD_TYPE_10G_DIRECT: 3482221167Sgnn vdev->ifm_optics = IFM_10G_TWINAX; 3483221167Sgnn strlcpy(ifm_name, "10GbE DA (Direct Attached)", ifm_len); 3484221167Sgnn break; 3485221167Sgnn 3486221167Sgnn case VXGE_HAL_DEVICE_PMD_TYPE_10G_CX4: 3487221167Sgnn vdev->ifm_optics = IFM_10G_CX4; 3488221167Sgnn strlcpy(ifm_name, "10GbE CX4", ifm_len); 3489221167Sgnn break; 3490221167Sgnn 3491221167Sgnn case VXGE_HAL_DEVICE_PMD_TYPE_10G_BASE_T: 3492221167Sgnn#if __FreeBSD_version >= 800000 3493221167Sgnn vdev->ifm_optics = IFM_10G_T; 3494221167Sgnn#endif 3495221167Sgnn strlcpy(ifm_name, "10GbE baseT", ifm_len); 3496221167Sgnn break; 3497221167Sgnn 3498221167Sgnn case VXGE_HAL_DEVICE_PMD_TYPE_10G_OTHER: 3499221167Sgnn strlcpy(ifm_name, "10GbE Other", ifm_len); 3500221167Sgnn break; 3501221167Sgnn 3502221167Sgnn case VXGE_HAL_DEVICE_PMD_TYPE_1G_SX: 3503221167Sgnn vdev->ifm_optics = IFM_1000_SX; 3504221167Sgnn strlcpy(ifm_name, "1GbE SX", ifm_len); 3505221167Sgnn break; 3506221167Sgnn 3507221167Sgnn case VXGE_HAL_DEVICE_PMD_TYPE_1G_LX: 3508221167Sgnn vdev->ifm_optics = IFM_1000_LX; 3509221167Sgnn strlcpy(ifm_name, "1GbE LX", ifm_len); 3510221167Sgnn break; 3511221167Sgnn 3512221167Sgnn case VXGE_HAL_DEVICE_PMD_TYPE_1G_CX: 3513221167Sgnn vdev->ifm_optics = IFM_1000_CX; 3514221167Sgnn strlcpy(ifm_name, "1GbE CX", ifm_len); 3515221167Sgnn break; 3516221167Sgnn 3517221167Sgnn case VXGE_HAL_DEVICE_PMD_TYPE_1G_BASE_T: 3518221167Sgnn vdev->ifm_optics = IFM_1000_T; 3519221167Sgnn strlcpy(ifm_name, "1GbE baseT", ifm_len); 3520221167Sgnn break; 3521221167Sgnn 3522221167Sgnn case VXGE_HAL_DEVICE_PMD_TYPE_1G_DIRECT: 3523221167Sgnn strlcpy(ifm_name, "1GbE DA (Direct Attached)", 3524221167Sgnn ifm_len); 3525221167Sgnn break; 3526221167Sgnn 3527221167Sgnn case VXGE_HAL_DEVICE_PMD_TYPE_1G_CX4: 3528221167Sgnn strlcpy(ifm_name, "1GbE CX4", ifm_len); 3529221167Sgnn break; 3530221167Sgnn 3531221167Sgnn case VXGE_HAL_DEVICE_PMD_TYPE_1G_OTHER: 3532221167Sgnn strlcpy(ifm_name, "1GbE Other", ifm_len); 3533221167Sgnn break; 3534221167Sgnn 3535221167Sgnn default: 3536221167Sgnn case VXGE_HAL_DEVICE_PMD_TYPE_UNKNOWN: 3537221167Sgnn strlcpy(ifm_name, "UNSUP", ifm_len); 3538221167Sgnn break; 3539221167Sgnn } 3540221167Sgnn} 3541221167Sgnn 3542221167Sgnnu32 3543221167Sgnnvxge_ring_length_get(u32 buffer_mode) 3544221167Sgnn{ 3545221167Sgnn return (VXGE_DEFAULT_RING_BLOCK * 3546221167Sgnn vxge_hal_ring_rxds_per_block_get(buffer_mode)); 3547221167Sgnn} 3548221167Sgnn 3549221167Sgnn/* 3550221167Sgnn * Removes trailing spaces padded 3551221167Sgnn * and NULL terminates strings 3552221167Sgnn */ 3553221167Sgnnstatic inline void 3554221167Sgnnvxge_null_terminate(char *str, size_t len) 3555221167Sgnn{ 3556221167Sgnn len--; 3557221167Sgnn while (*str && (*str != ' ') && (len != 0)) 3558221167Sgnn ++str; 3559221167Sgnn 3560221167Sgnn --len; 3561221167Sgnn if (*str) 3562221167Sgnn *str = '\0'; 3563221167Sgnn} 3564221167Sgnn 3565221167Sgnn/* 3566221167Sgnn * vxge_ioctl 3567221167Sgnn * Callback to control the device 3568221167Sgnn */ 3569221167Sgnnint 3570221167Sgnnvxge_ioctl(ifnet_t ifp, u_long command, caddr_t data) 3571221167Sgnn{ 3572221167Sgnn int mask, err = 0; 3573221167Sgnn vxge_dev_t *vdev = (vxge_dev_t *) ifp->if_softc; 3574221167Sgnn struct ifreq *ifr = (struct ifreq *) data; 3575221167Sgnn 3576221167Sgnn if (!vdev->is_active) 3577221167Sgnn return (EBUSY); 3578221167Sgnn 3579221167Sgnn switch (command) { 3580221167Sgnn /* Set/Get ifnet address */ 3581221167Sgnn case SIOCSIFADDR: 3582221167Sgnn case SIOCGIFADDR: 3583221167Sgnn ether_ioctl(ifp, command, data); 3584221167Sgnn break; 3585221167Sgnn 3586221167Sgnn /* Set Interface MTU */ 3587221167Sgnn case SIOCSIFMTU: 3588221167Sgnn err = vxge_change_mtu(vdev, (unsigned long)ifr->ifr_mtu); 3589221167Sgnn break; 3590221167Sgnn 3591221167Sgnn /* Set Interface Flags */ 3592221167Sgnn case SIOCSIFFLAGS: 3593221167Sgnn VXGE_DRV_LOCK(vdev); 3594221167Sgnn if (ifp->if_flags & IFF_UP) { 3595221167Sgnn if ((ifp->if_drv_flags & IFF_DRV_RUNNING)) { 3596221167Sgnn if ((ifp->if_flags ^ vdev->if_flags) & 3597221167Sgnn (IFF_PROMISC | IFF_ALLMULTI)) 3598221167Sgnn vxge_promisc_set(vdev); 3599221167Sgnn } else { 3600221167Sgnn vxge_init_locked(vdev); 3601221167Sgnn } 3602221167Sgnn } else { 3603221167Sgnn if (ifp->if_drv_flags & IFF_DRV_RUNNING) 3604221167Sgnn vxge_stop_locked(vdev); 3605221167Sgnn } 3606221167Sgnn vdev->if_flags = ifp->if_flags; 3607221167Sgnn VXGE_DRV_UNLOCK(vdev); 3608221167Sgnn break; 3609221167Sgnn 3610221167Sgnn /* Add/delete multicast address */ 3611221167Sgnn case SIOCADDMULTI: 3612221167Sgnn case SIOCDELMULTI: 3613221167Sgnn break; 3614221167Sgnn 3615221167Sgnn /* Get/Set Interface Media */ 3616221167Sgnn case SIOCSIFMEDIA: 3617221167Sgnn case SIOCGIFMEDIA: 3618221167Sgnn err = ifmedia_ioctl(ifp, ifr, &vdev->media, command); 3619221167Sgnn break; 3620221167Sgnn 3621221167Sgnn /* Set Capabilities */ 3622221167Sgnn case SIOCSIFCAP: 3623221167Sgnn VXGE_DRV_LOCK(vdev); 3624221167Sgnn mask = ifr->ifr_reqcap ^ ifp->if_capenable; 3625221167Sgnn 3626221167Sgnn if (mask & IFCAP_TXCSUM) { 3627221167Sgnn ifp->if_capenable ^= IFCAP_TXCSUM; 3628221167Sgnn ifp->if_hwassist ^= (CSUM_TCP | CSUM_UDP | CSUM_IP); 3629221167Sgnn 3630221167Sgnn if ((ifp->if_capenable & IFCAP_TSO) && 3631221167Sgnn !(ifp->if_capenable & IFCAP_TXCSUM)) { 3632221167Sgnn 3633221167Sgnn ifp->if_capenable &= ~IFCAP_TSO; 3634221167Sgnn ifp->if_hwassist &= ~CSUM_TSO; 3635221167Sgnn if_printf(ifp, "TSO Disabled\n"); 3636221167Sgnn } 3637221167Sgnn } 3638221167Sgnn if (mask & IFCAP_RXCSUM) 3639221167Sgnn ifp->if_capenable ^= IFCAP_RXCSUM; 3640221167Sgnn 3641221167Sgnn if (mask & IFCAP_TSO4) { 3642221167Sgnn ifp->if_capenable ^= IFCAP_TSO4; 3643221167Sgnn 3644221167Sgnn if (ifp->if_capenable & IFCAP_TSO) { 3645221167Sgnn if (ifp->if_capenable & IFCAP_TXCSUM) { 3646221167Sgnn ifp->if_hwassist |= CSUM_TSO; 3647221167Sgnn if_printf(ifp, "TSO Enabled\n"); 3648221167Sgnn } else { 3649221167Sgnn ifp->if_capenable &= ~IFCAP_TSO; 3650221167Sgnn ifp->if_hwassist &= ~CSUM_TSO; 3651221167Sgnn if_printf(ifp, 3652221167Sgnn "Enable tx checksum offload \ 3653221167Sgnn first.\n"); 3654221167Sgnn err = EAGAIN; 3655221167Sgnn } 3656221167Sgnn } else { 3657221167Sgnn ifp->if_hwassist &= ~CSUM_TSO; 3658221167Sgnn if_printf(ifp, "TSO Disabled\n"); 3659221167Sgnn } 3660221167Sgnn } 3661221167Sgnn if (mask & IFCAP_LRO) 3662221167Sgnn ifp->if_capenable ^= IFCAP_LRO; 3663221167Sgnn 3664221167Sgnn if (mask & IFCAP_VLAN_HWTAGGING) 3665221167Sgnn ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING; 3666221167Sgnn 3667221167Sgnn if (mask & IFCAP_VLAN_MTU) 3668221167Sgnn ifp->if_capenable ^= IFCAP_VLAN_MTU; 3669221167Sgnn 3670221167Sgnn if (mask & IFCAP_VLAN_HWCSUM) 3671221167Sgnn ifp->if_capenable ^= IFCAP_VLAN_HWCSUM; 3672221167Sgnn 3673221167Sgnn#if __FreeBSD_version >= 800000 3674221167Sgnn if (mask & IFCAP_VLAN_HWTSO) 3675221167Sgnn ifp->if_capenable ^= IFCAP_VLAN_HWTSO; 3676221167Sgnn#endif 3677221167Sgnn 3678221167Sgnn#if defined(VLAN_CAPABILITIES) 3679221167Sgnn VLAN_CAPABILITIES(ifp); 3680221167Sgnn#endif 3681221167Sgnn 3682221167Sgnn VXGE_DRV_UNLOCK(vdev); 3683221167Sgnn break; 3684221167Sgnn 3685221167Sgnn case SIOCGPRIVATE_0: 3686221167Sgnn VXGE_DRV_LOCK(vdev); 3687221167Sgnn err = vxge_ioctl_stats(vdev, ifr); 3688221167Sgnn VXGE_DRV_UNLOCK(vdev); 3689221167Sgnn break; 3690221167Sgnn 3691221167Sgnn case SIOCGPRIVATE_1: 3692221167Sgnn VXGE_DRV_LOCK(vdev); 3693221167Sgnn err = vxge_ioctl_regs(vdev, ifr); 3694221167Sgnn VXGE_DRV_UNLOCK(vdev); 3695221167Sgnn break; 3696221167Sgnn 3697221167Sgnn default: 3698221167Sgnn err = ether_ioctl(ifp, command, data); 3699221167Sgnn break; 3700221167Sgnn } 3701221167Sgnn 3702221167Sgnn return (err); 3703221167Sgnn} 3704221167Sgnn 3705221167Sgnn/* 3706221167Sgnn * vxge_ioctl_regs 3707221167Sgnn * IOCTL to get registers 3708221167Sgnn */ 3709221167Sgnnint 3710221167Sgnnvxge_ioctl_regs(vxge_dev_t *vdev, struct ifreq *ifr) 3711221167Sgnn{ 3712221167Sgnn u64 value = 0x0; 3713221167Sgnn u32 vp_id = 0; 3714221167Sgnn u32 offset, reqd_size = 0; 3715221167Sgnn int i, err = EINVAL; 3716221167Sgnn 3717221167Sgnn char *command = (char *) ifr->ifr_data; 3718221167Sgnn void *reg_info = (void *) ifr->ifr_data; 3719221167Sgnn 3720221167Sgnn vxge_vpath_t *vpath; 3721221167Sgnn vxge_hal_status_e status = VXGE_HAL_OK; 3722221167Sgnn vxge_hal_mgmt_reg_type_e regs_type; 3723221167Sgnn 3724221167Sgnn switch (*command) { 3725221167Sgnn case vxge_hal_mgmt_reg_type_pcicfgmgmt: 3726221167Sgnn if (vdev->is_privilaged) { 3727221167Sgnn reqd_size = sizeof(vxge_hal_pcicfgmgmt_reg_t); 3728221167Sgnn regs_type = vxge_hal_mgmt_reg_type_pcicfgmgmt; 3729221167Sgnn } 3730221167Sgnn break; 3731221167Sgnn 3732221167Sgnn case vxge_hal_mgmt_reg_type_mrpcim: 3733221167Sgnn if (vdev->is_privilaged) { 3734221167Sgnn reqd_size = sizeof(vxge_hal_mrpcim_reg_t); 3735221167Sgnn regs_type = vxge_hal_mgmt_reg_type_mrpcim; 3736221167Sgnn } 3737221167Sgnn break; 3738221167Sgnn 3739221167Sgnn case vxge_hal_mgmt_reg_type_srpcim: 3740221167Sgnn if (vdev->is_privilaged) { 3741221167Sgnn reqd_size = sizeof(vxge_hal_srpcim_reg_t); 3742221167Sgnn regs_type = vxge_hal_mgmt_reg_type_srpcim; 3743221167Sgnn } 3744221167Sgnn break; 3745221167Sgnn 3746221167Sgnn case vxge_hal_mgmt_reg_type_memrepair: 3747221167Sgnn if (vdev->is_privilaged) { 3748221167Sgnn /* reqd_size = sizeof(vxge_hal_memrepair_reg_t); */ 3749221167Sgnn regs_type = vxge_hal_mgmt_reg_type_memrepair; 3750221167Sgnn } 3751221167Sgnn break; 3752221167Sgnn 3753221167Sgnn case vxge_hal_mgmt_reg_type_legacy: 3754221167Sgnn reqd_size = sizeof(vxge_hal_legacy_reg_t); 3755221167Sgnn regs_type = vxge_hal_mgmt_reg_type_legacy; 3756221167Sgnn break; 3757221167Sgnn 3758221167Sgnn case vxge_hal_mgmt_reg_type_toc: 3759221167Sgnn reqd_size = sizeof(vxge_hal_toc_reg_t); 3760221167Sgnn regs_type = vxge_hal_mgmt_reg_type_toc; 3761221167Sgnn break; 3762221167Sgnn 3763221167Sgnn case vxge_hal_mgmt_reg_type_common: 3764221167Sgnn reqd_size = sizeof(vxge_hal_common_reg_t); 3765221167Sgnn regs_type = vxge_hal_mgmt_reg_type_common; 3766221167Sgnn break; 3767221167Sgnn 3768221167Sgnn case vxge_hal_mgmt_reg_type_vpmgmt: 3769221167Sgnn reqd_size = sizeof(vxge_hal_vpmgmt_reg_t); 3770221167Sgnn regs_type = vxge_hal_mgmt_reg_type_vpmgmt; 3771221167Sgnn vpath = &(vdev->vpaths[*((u32 *) reg_info + 1)]); 3772221167Sgnn vp_id = vpath->vp_id; 3773221167Sgnn break; 3774221167Sgnn 3775221167Sgnn case vxge_hal_mgmt_reg_type_vpath: 3776221167Sgnn reqd_size = sizeof(vxge_hal_vpath_reg_t); 3777221167Sgnn regs_type = vxge_hal_mgmt_reg_type_vpath; 3778221167Sgnn vpath = &(vdev->vpaths[*((u32 *) reg_info + 1)]); 3779221167Sgnn vp_id = vpath->vp_id; 3780221167Sgnn break; 3781221167Sgnn 3782221167Sgnn case VXGE_GET_VPATH_COUNT: 3783221167Sgnn *((u32 *) reg_info) = vdev->no_of_vpath; 3784221167Sgnn err = 0; 3785221167Sgnn break; 3786221167Sgnn 3787221167Sgnn default: 3788221167Sgnn reqd_size = 0; 3789221167Sgnn break; 3790221167Sgnn } 3791221167Sgnn 3792221167Sgnn if (reqd_size) { 3793221167Sgnn for (i = 0, offset = 0; offset < reqd_size; 3794221167Sgnn i++, offset += 0x0008) { 3795221167Sgnn value = 0x0; 3796221167Sgnn status = vxge_hal_mgmt_reg_read(vdev->devh, regs_type, 3797221167Sgnn vp_id, offset, &value); 3798221167Sgnn 3799221167Sgnn err = (status != VXGE_HAL_OK) ? EINVAL : 0; 3800221167Sgnn if (err == EINVAL) 3801221167Sgnn break; 3802221167Sgnn 3803221167Sgnn *((u64 *) ((u64 *) reg_info + i)) = value; 3804221167Sgnn } 3805221167Sgnn } 3806221167Sgnn return (err); 3807221167Sgnn} 3808221167Sgnn 3809221167Sgnn/* 3810221167Sgnn * vxge_ioctl_stats 3811221167Sgnn * IOCTL to get statistics 3812221167Sgnn */ 3813221167Sgnnint 3814221167Sgnnvxge_ioctl_stats(vxge_dev_t *vdev, struct ifreq *ifr) 3815221167Sgnn{ 3816221167Sgnn int i, retsize, err = EINVAL; 3817221167Sgnn u32 bufsize; 3818221167Sgnn 3819221167Sgnn vxge_vpath_t *vpath; 3820221167Sgnn vxge_bw_info_t *bw_info; 3821221167Sgnn vxge_port_info_t *port_info; 3822221167Sgnn vxge_drv_stats_t *drv_stat; 3823221167Sgnn 3824221167Sgnn char *buffer = NULL; 3825221167Sgnn char *command = (char *) ifr->ifr_data; 3826221167Sgnn vxge_hal_status_e status = VXGE_HAL_OK; 3827221167Sgnn 3828221167Sgnn switch (*command) { 3829221167Sgnn case VXGE_GET_PCI_CONF: 3830221167Sgnn bufsize = VXGE_STATS_BUFFER_SIZE; 3831221167Sgnn buffer = (char *) vxge_mem_alloc(bufsize); 3832221167Sgnn if (buffer != NULL) { 3833221167Sgnn status = vxge_hal_aux_pci_config_read(vdev->devh, 3834221167Sgnn bufsize, buffer, &retsize); 3835221167Sgnn if (status == VXGE_HAL_OK) 3836221167Sgnn err = copyout(buffer, ifr->ifr_data, retsize); 3837221167Sgnn else 3838221167Sgnn device_printf(vdev->ndev, 3839221167Sgnn "failed pciconfig statistics query\n"); 3840221167Sgnn 3841221167Sgnn vxge_mem_free(buffer, bufsize); 3842221167Sgnn } 3843221167Sgnn break; 3844221167Sgnn 3845221167Sgnn case VXGE_GET_MRPCIM_STATS: 3846221167Sgnn if (!vdev->is_privilaged) 3847221167Sgnn break; 3848221167Sgnn 3849221167Sgnn bufsize = VXGE_STATS_BUFFER_SIZE; 3850221167Sgnn buffer = (char *) vxge_mem_alloc(bufsize); 3851221167Sgnn if (buffer != NULL) { 3852221167Sgnn status = vxge_hal_aux_stats_mrpcim_read(vdev->devh, 3853221167Sgnn bufsize, buffer, &retsize); 3854221167Sgnn if (status == VXGE_HAL_OK) 3855221167Sgnn err = copyout(buffer, ifr->ifr_data, retsize); 3856221167Sgnn else 3857221167Sgnn device_printf(vdev->ndev, 3858221167Sgnn "failed mrpcim statistics query\n"); 3859221167Sgnn 3860221167Sgnn vxge_mem_free(buffer, bufsize); 3861221167Sgnn } 3862221167Sgnn break; 3863221167Sgnn 3864221167Sgnn case VXGE_GET_DEVICE_STATS: 3865221167Sgnn bufsize = VXGE_STATS_BUFFER_SIZE; 3866221167Sgnn buffer = (char *) vxge_mem_alloc(bufsize); 3867221167Sgnn if (buffer != NULL) { 3868221167Sgnn status = vxge_hal_aux_stats_device_read(vdev->devh, 3869221167Sgnn bufsize, buffer, &retsize); 3870221167Sgnn if (status == VXGE_HAL_OK) 3871221167Sgnn err = copyout(buffer, ifr->ifr_data, retsize); 3872221167Sgnn else 3873221167Sgnn device_printf(vdev->ndev, 3874221167Sgnn "failed device statistics query\n"); 3875221167Sgnn 3876221167Sgnn vxge_mem_free(buffer, bufsize); 3877221167Sgnn } 3878221167Sgnn break; 3879221167Sgnn 3880221167Sgnn case VXGE_GET_DEVICE_HWINFO: 3881221167Sgnn bufsize = sizeof(vxge_device_hw_info_t); 3882221167Sgnn buffer = (char *) vxge_mem_alloc(bufsize); 3883221167Sgnn if (buffer != NULL) { 3884221167Sgnn vxge_os_memcpy( 3885221167Sgnn &(((vxge_device_hw_info_t *) buffer)->hw_info), 3886221167Sgnn &vdev->config.hw_info, 3887221167Sgnn sizeof(vxge_hal_device_hw_info_t)); 3888221167Sgnn 3889221167Sgnn ((vxge_device_hw_info_t *) buffer)->port_mode = 3890221167Sgnn vdev->port_mode; 3891221167Sgnn 3892221167Sgnn ((vxge_device_hw_info_t *) buffer)->port_failure = 3893221167Sgnn vdev->port_failure; 3894221167Sgnn 3895221167Sgnn err = copyout(buffer, ifr->ifr_data, bufsize); 3896221167Sgnn if (err != 0) 3897221167Sgnn device_printf(vdev->ndev, 3898221167Sgnn "failed device hardware info query\n"); 3899221167Sgnn 3900221167Sgnn vxge_mem_free(buffer, bufsize); 3901221167Sgnn } 3902221167Sgnn break; 3903221167Sgnn 3904221167Sgnn case VXGE_GET_DRIVER_STATS: 3905221167Sgnn bufsize = sizeof(vxge_drv_stats_t) * vdev->no_of_vpath; 3906221167Sgnn drv_stat = (vxge_drv_stats_t *) vxge_mem_alloc(bufsize); 3907221167Sgnn if (drv_stat != NULL) { 3908221167Sgnn for (i = 0; i < vdev->no_of_vpath; i++) { 3909221167Sgnn vpath = &(vdev->vpaths[i]); 3910221167Sgnn 3911221167Sgnn vpath->driver_stats.rx_lro_queued += 3912221167Sgnn vpath->lro.lro_queued; 3913221167Sgnn 3914221167Sgnn vpath->driver_stats.rx_lro_flushed += 3915221167Sgnn vpath->lro.lro_flushed; 3916221167Sgnn 3917221167Sgnn vxge_os_memcpy(&drv_stat[i], 3918221167Sgnn &(vpath->driver_stats), 3919221167Sgnn sizeof(vxge_drv_stats_t)); 3920221167Sgnn } 3921221167Sgnn 3922221167Sgnn err = copyout(drv_stat, ifr->ifr_data, bufsize); 3923221167Sgnn if (err != 0) 3924221167Sgnn device_printf(vdev->ndev, 3925221167Sgnn "failed driver statistics query\n"); 3926221167Sgnn 3927221167Sgnn vxge_mem_free(drv_stat, bufsize); 3928221167Sgnn } 3929221167Sgnn break; 3930221167Sgnn 3931221167Sgnn case VXGE_GET_BANDWIDTH: 3932221167Sgnn bw_info = (vxge_bw_info_t *) ifr->ifr_data; 3933221167Sgnn 3934221167Sgnn if ((vdev->config.hw_info.func_id != 0) && 3935221167Sgnn (vdev->hw_fw_version < VXGE_FW_VERSION(1, 8, 0))) 3936221167Sgnn break; 3937221167Sgnn 3938221167Sgnn if (vdev->config.hw_info.func_id != 0) 3939221167Sgnn bw_info->func_id = vdev->config.hw_info.func_id; 3940221167Sgnn 3941221167Sgnn status = vxge_bw_priority_get(vdev, bw_info); 3942221167Sgnn if (status != VXGE_HAL_OK) 3943221167Sgnn break; 3944221167Sgnn 3945221167Sgnn err = copyout(bw_info, ifr->ifr_data, sizeof(vxge_bw_info_t)); 3946221167Sgnn break; 3947221167Sgnn 3948221167Sgnn case VXGE_SET_BANDWIDTH: 3949221167Sgnn if (vdev->is_privilaged) 3950221167Sgnn err = vxge_bw_priority_set(vdev, ifr); 3951221167Sgnn break; 3952221167Sgnn 3953221167Sgnn case VXGE_SET_PORT_MODE: 3954221167Sgnn if (vdev->is_privilaged) { 3955221167Sgnn if (vdev->config.hw_info.ports == VXGE_DUAL_PORT_MODE) { 3956221167Sgnn port_info = (vxge_port_info_t *) ifr->ifr_data; 3957221167Sgnn vdev->config.port_mode = port_info->port_mode; 3958221167Sgnn err = vxge_port_mode_update(vdev); 3959221167Sgnn if (err != ENXIO) 3960221167Sgnn err = VXGE_HAL_FAIL; 3961221167Sgnn else { 3962221167Sgnn err = VXGE_HAL_OK; 3963221167Sgnn device_printf(vdev->ndev, 3964221167Sgnn "PLEASE POWER CYCLE THE SYSTEM\n"); 3965221167Sgnn } 3966221167Sgnn } 3967221167Sgnn } 3968221167Sgnn break; 3969221167Sgnn 3970221167Sgnn case VXGE_GET_PORT_MODE: 3971221167Sgnn if (vdev->is_privilaged) { 3972221167Sgnn if (vdev->config.hw_info.ports == VXGE_DUAL_PORT_MODE) { 3973221167Sgnn port_info = (vxge_port_info_t *) ifr->ifr_data; 3974221167Sgnn err = vxge_port_mode_get(vdev, port_info); 3975221167Sgnn if (err == VXGE_HAL_OK) { 3976221167Sgnn err = copyout(port_info, ifr->ifr_data, 3977221167Sgnn sizeof(vxge_port_info_t)); 3978221167Sgnn } 3979221167Sgnn } 3980221167Sgnn } 3981221167Sgnn break; 3982221167Sgnn 3983221167Sgnn default: 3984221167Sgnn break; 3985221167Sgnn } 3986221167Sgnn 3987221167Sgnn return (err); 3988221167Sgnn} 3989221167Sgnn 3990221167Sgnnint 3991221167Sgnnvxge_bw_priority_config(vxge_dev_t *vdev) 3992221167Sgnn{ 3993221167Sgnn u32 i; 3994221167Sgnn int err = EINVAL; 3995221167Sgnn 3996221167Sgnn for (i = 0; i < vdev->no_of_func; i++) { 3997221167Sgnn err = vxge_bw_priority_update(vdev, i, TRUE); 3998221167Sgnn if (err != 0) 3999221167Sgnn break; 4000221167Sgnn } 4001221167Sgnn 4002221167Sgnn return (err); 4003221167Sgnn} 4004221167Sgnn 4005221167Sgnnint 4006221167Sgnnvxge_bw_priority_set(vxge_dev_t *vdev, struct ifreq *ifr) 4007221167Sgnn{ 4008221167Sgnn int err; 4009221167Sgnn u32 func_id; 4010221167Sgnn vxge_bw_info_t *bw_info; 4011221167Sgnn 4012221167Sgnn bw_info = (vxge_bw_info_t *) ifr->ifr_data; 4013221167Sgnn func_id = bw_info->func_id; 4014221167Sgnn 4015221167Sgnn vdev->config.bw_info[func_id].priority = bw_info->priority; 4016221167Sgnn vdev->config.bw_info[func_id].bandwidth = bw_info->bandwidth; 4017221167Sgnn 4018221167Sgnn err = vxge_bw_priority_update(vdev, func_id, FALSE); 4019221167Sgnn 4020221167Sgnn return (err); 4021221167Sgnn} 4022221167Sgnn 4023221167Sgnnint 4024221167Sgnnvxge_bw_priority_update(vxge_dev_t *vdev, u32 func_id, bool binit) 4025221167Sgnn{ 4026221167Sgnn u32 i, set = 0; 4027221167Sgnn u32 bandwidth, priority, vpath_count; 4028221167Sgnn u64 vpath_list[VXGE_HAL_MAX_VIRTUAL_PATHS]; 4029221167Sgnn 4030221167Sgnn vxge_hal_device_t *hldev; 4031221167Sgnn vxge_hal_vp_config_t *vp_config; 4032221167Sgnn vxge_hal_status_e status = VXGE_HAL_OK; 4033221167Sgnn 4034221167Sgnn hldev = vdev->devh; 4035221167Sgnn 4036221167Sgnn status = vxge_hal_get_vpath_list(vdev->devh, func_id, 4037221167Sgnn vpath_list, &vpath_count); 4038221167Sgnn 4039221167Sgnn if (status != VXGE_HAL_OK) 4040221167Sgnn return (status); 4041221167Sgnn 4042221167Sgnn for (i = 0; i < vpath_count; i++) { 4043221167Sgnn vp_config = &(hldev->config.vp_config[vpath_list[i]]); 4044221167Sgnn 4045221167Sgnn /* Configure Bandwidth */ 4046221167Sgnn if (vdev->config.bw_info[func_id].bandwidth != 4047221167Sgnn VXGE_HAL_VPATH_BW_LIMIT_DEFAULT) { 4048221167Sgnn 4049221167Sgnn set = 1; 4050221167Sgnn bandwidth = vdev->config.bw_info[func_id].bandwidth; 4051221167Sgnn if (bandwidth < VXGE_HAL_VPATH_BW_LIMIT_MIN || 4052221167Sgnn bandwidth > VXGE_HAL_VPATH_BW_LIMIT_MAX) { 4053221167Sgnn 4054221167Sgnn bandwidth = VXGE_HAL_VPATH_BW_LIMIT_DEFAULT; 4055221167Sgnn } 4056221167Sgnn vp_config->bandwidth = bandwidth; 4057221167Sgnn } 4058221167Sgnn 4059221167Sgnn /* 4060221167Sgnn * If b/w limiting is enabled on any of the 4061221167Sgnn * VFs, then for remaining VFs set the priority to 3 4062221167Sgnn * and b/w limiting to max i.e 10 Gb) 4063221167Sgnn */ 4064221167Sgnn if (vp_config->bandwidth == VXGE_HAL_VPATH_BW_LIMIT_DEFAULT) 4065221167Sgnn vp_config->bandwidth = VXGE_HAL_VPATH_BW_LIMIT_MAX; 4066221167Sgnn 4067221167Sgnn if (binit && vdev->config.low_latency) { 4068221167Sgnn if (func_id == 0) 4069221167Sgnn vdev->config.bw_info[func_id].priority = 4070221167Sgnn VXGE_DEFAULT_VPATH_PRIORITY_HIGH; 4071221167Sgnn } 4072221167Sgnn 4073221167Sgnn /* Configure Priority */ 4074221167Sgnn if (vdev->config.bw_info[func_id].priority != 4075221167Sgnn VXGE_HAL_VPATH_PRIORITY_DEFAULT) { 4076221167Sgnn 4077221167Sgnn set = 1; 4078221167Sgnn priority = vdev->config.bw_info[func_id].priority; 4079221167Sgnn if (priority < VXGE_HAL_VPATH_PRIORITY_MIN || 4080221167Sgnn priority > VXGE_HAL_VPATH_PRIORITY_MAX) { 4081221167Sgnn 4082221167Sgnn priority = VXGE_HAL_VPATH_PRIORITY_DEFAULT; 4083221167Sgnn } 4084221167Sgnn vp_config->priority = priority; 4085221167Sgnn 4086221167Sgnn } else if (vdev->config.low_latency) { 4087221167Sgnn set = 1; 4088221167Sgnn vp_config->priority = VXGE_DEFAULT_VPATH_PRIORITY_LOW; 4089221167Sgnn } 4090221167Sgnn 4091221167Sgnn if (set == 1) { 4092221167Sgnn status = vxge_hal_rx_bw_priority_set(vdev->devh, 4093221167Sgnn vpath_list[i]); 4094221167Sgnn if (status != VXGE_HAL_OK) 4095221167Sgnn break; 4096221167Sgnn 4097221167Sgnn if (vpath_list[i] < VXGE_HAL_TX_BW_VPATH_LIMIT) { 4098221167Sgnn status = vxge_hal_tx_bw_priority_set( 4099221167Sgnn vdev->devh, vpath_list[i]); 4100221167Sgnn if (status != VXGE_HAL_OK) 4101221167Sgnn break; 4102221167Sgnn } 4103221167Sgnn } 4104221167Sgnn } 4105221167Sgnn 4106221167Sgnn return ((status == VXGE_HAL_OK) ? 0 : EINVAL); 4107221167Sgnn} 4108221167Sgnn 4109221167Sgnn/* 4110221167Sgnn * vxge_intr_coalesce_tx 4111221167Sgnn * Changes interrupt coalescing if the interrupts are not within a range 4112221167Sgnn * Return Value: Nothing 4113221167Sgnn */ 4114221167Sgnnvoid 4115221167Sgnnvxge_intr_coalesce_tx(vxge_vpath_t *vpath) 4116221167Sgnn{ 4117221167Sgnn u32 timer; 4118221167Sgnn 4119221167Sgnn if (!vpath->tx_intr_coalesce) 4120221167Sgnn return; 4121221167Sgnn 4122221167Sgnn vpath->tx_interrupts++; 4123221167Sgnn if (ticks > vpath->tx_ticks + hz/100) { 4124221167Sgnn 4125221167Sgnn vpath->tx_ticks = ticks; 4126221167Sgnn timer = vpath->tti_rtimer_val; 4127221167Sgnn if (vpath->tx_interrupts > VXGE_MAX_TX_INTERRUPT_COUNT) { 4128221167Sgnn if (timer != VXGE_TTI_RTIMER_ADAPT_VAL) { 4129221167Sgnn vpath->tti_rtimer_val = 4130221167Sgnn VXGE_TTI_RTIMER_ADAPT_VAL; 4131221167Sgnn 4132221167Sgnn vxge_hal_vpath_dynamic_tti_rtimer_set( 4133221167Sgnn vpath->handle, vpath->tti_rtimer_val); 4134221167Sgnn } 4135221167Sgnn } else { 4136221167Sgnn if (timer != 0) { 4137221167Sgnn vpath->tti_rtimer_val = 0; 4138221167Sgnn vxge_hal_vpath_dynamic_tti_rtimer_set( 4139221167Sgnn vpath->handle, vpath->tti_rtimer_val); 4140221167Sgnn } 4141221167Sgnn } 4142221167Sgnn vpath->tx_interrupts = 0; 4143221167Sgnn } 4144221167Sgnn} 4145221167Sgnn 4146221167Sgnn/* 4147221167Sgnn * vxge_intr_coalesce_rx 4148221167Sgnn * Changes interrupt coalescing if the interrupts are not within a range 4149221167Sgnn * Return Value: Nothing 4150221167Sgnn */ 4151221167Sgnnvoid 4152221167Sgnnvxge_intr_coalesce_rx(vxge_vpath_t *vpath) 4153221167Sgnn{ 4154221167Sgnn u32 timer; 4155221167Sgnn 4156221167Sgnn if (!vpath->rx_intr_coalesce) 4157221167Sgnn return; 4158221167Sgnn 4159221167Sgnn vpath->rx_interrupts++; 4160221167Sgnn if (ticks > vpath->rx_ticks + hz/100) { 4161221167Sgnn 4162221167Sgnn vpath->rx_ticks = ticks; 4163221167Sgnn timer = vpath->rti_rtimer_val; 4164221167Sgnn 4165221167Sgnn if (vpath->rx_interrupts > VXGE_MAX_RX_INTERRUPT_COUNT) { 4166221167Sgnn if (timer != VXGE_RTI_RTIMER_ADAPT_VAL) { 4167221167Sgnn vpath->rti_rtimer_val = 4168221167Sgnn VXGE_RTI_RTIMER_ADAPT_VAL; 4169221167Sgnn 4170221167Sgnn vxge_hal_vpath_dynamic_rti_rtimer_set( 4171221167Sgnn vpath->handle, vpath->rti_rtimer_val); 4172221167Sgnn } 4173221167Sgnn } else { 4174221167Sgnn if (timer != 0) { 4175221167Sgnn vpath->rti_rtimer_val = 0; 4176221167Sgnn vxge_hal_vpath_dynamic_rti_rtimer_set( 4177221167Sgnn vpath->handle, vpath->rti_rtimer_val); 4178221167Sgnn } 4179221167Sgnn } 4180221167Sgnn vpath->rx_interrupts = 0; 4181221167Sgnn } 4182221167Sgnn} 4183221167Sgnn 4184221167Sgnn/* 4185221167Sgnn * vxge_methods FreeBSD device interface entry points 4186221167Sgnn */ 4187221167Sgnnstatic device_method_t vxge_methods[] = { 4188221167Sgnn DEVMETHOD(device_probe, vxge_probe), 4189221167Sgnn DEVMETHOD(device_attach, vxge_attach), 4190221167Sgnn DEVMETHOD(device_detach, vxge_detach), 4191221167Sgnn DEVMETHOD(device_shutdown, vxge_shutdown), 4192221167Sgnn {0, 0} 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