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