1*a23fd118Syl /* 2*a23fd118Syl * CDDL HEADER START 3*a23fd118Syl * 4*a23fd118Syl * The contents of this file are subject to the terms of the 5*a23fd118Syl * Common Development and Distribution License (the "License"). 6*a23fd118Syl * You may not use this file except in compliance with the License. 7*a23fd118Syl * 8*a23fd118Syl * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*a23fd118Syl * or http://www.opensolaris.org/os/licensing. 10*a23fd118Syl * See the License for the specific language governing permissions 11*a23fd118Syl * and limitations under the License. 12*a23fd118Syl * 13*a23fd118Syl * When distributing Covered Code, include this CDDL HEADER in each 14*a23fd118Syl * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*a23fd118Syl * If applicable, add the following below this CDDL HEADER, with the 16*a23fd118Syl * fields enclosed by brackets "[]" replaced with your own identifying 17*a23fd118Syl * information: Portions Copyright [yyyy] [name of copyright owner] 18*a23fd118Syl * 19*a23fd118Syl * CDDL HEADER END 20*a23fd118Syl */ 21*a23fd118Syl 22*a23fd118Syl /* 23*a23fd118Syl * Copyright (c) 2002-2005 Neterion, Inc. 24*a23fd118Syl * All right Reserved. 25*a23fd118Syl * 26*a23fd118Syl * FileName : xgehal-mgmt.c 27*a23fd118Syl * 28*a23fd118Syl * Description: Xframe-family management facility implementation 29*a23fd118Syl * 30*a23fd118Syl * Created: 1 September 2004 31*a23fd118Syl */ 32*a23fd118Syl 33*a23fd118Syl #include "xgehal-mgmt.h" 34*a23fd118Syl #include "xgehal-driver.h" 35*a23fd118Syl #include "xgehal-device.h" 36*a23fd118Syl 37*a23fd118Syl /** 38*a23fd118Syl * xge_hal_mgmt_about - Retrieve about info. 39*a23fd118Syl * @devh: HAL device handle. 40*a23fd118Syl * @about_info: Filled in by HAL. See xge_hal_mgmt_about_info_t{}. 41*a23fd118Syl * @size: Size of the @about_info buffer. HAL will return error if the 42*a23fd118Syl * size is smaller than sizeof(xge_hal_mgmt_about_info_t). 43*a23fd118Syl * 44*a23fd118Syl * Retrieve information such as PCI device and vendor IDs, board 45*a23fd118Syl * revision number, HAL version number, etc. 46*a23fd118Syl * 47*a23fd118Syl * Returns: XGE_HAL_OK - success; 48*a23fd118Syl * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid. 49*a23fd118Syl * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching. 50*a23fd118Syl * XGE_HAL_FAIL - Failed to retrieve the information. 51*a23fd118Syl * 52*a23fd118Syl * See also: xge_hal_mgmt_about_info_t{}. 53*a23fd118Syl */ 54*a23fd118Syl xge_hal_status_e 55*a23fd118Syl xge_hal_mgmt_about(xge_hal_device_h devh, xge_hal_mgmt_about_info_t *about_info, 56*a23fd118Syl int size) 57*a23fd118Syl { 58*a23fd118Syl xge_hal_device_t *hldev = (xge_hal_device_t*)devh; 59*a23fd118Syl 60*a23fd118Syl if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) { 61*a23fd118Syl return XGE_HAL_ERR_INVALID_DEVICE; 62*a23fd118Syl } 63*a23fd118Syl 64*a23fd118Syl if (size != sizeof(xge_hal_mgmt_about_info_t)) { 65*a23fd118Syl return XGE_HAL_ERR_VERSION_CONFLICT; 66*a23fd118Syl } 67*a23fd118Syl 68*a23fd118Syl xge_os_pci_read16(hldev->pdev, hldev->cfgh, 69*a23fd118Syl xge_offsetof(xge_hal_pci_config_le_t, vendor_id), 70*a23fd118Syl &about_info->vendor); 71*a23fd118Syl 72*a23fd118Syl xge_os_pci_read16(hldev->pdev, hldev->cfgh, 73*a23fd118Syl xge_offsetof(xge_hal_pci_config_le_t, device_id), 74*a23fd118Syl &about_info->device); 75*a23fd118Syl 76*a23fd118Syl xge_os_pci_read16(hldev->pdev, hldev->cfgh, 77*a23fd118Syl xge_offsetof(xge_hal_pci_config_le_t, subsystem_vendor_id), 78*a23fd118Syl &about_info->subsys_vendor); 79*a23fd118Syl 80*a23fd118Syl xge_os_pci_read16(hldev->pdev, hldev->cfgh, 81*a23fd118Syl xge_offsetof(xge_hal_pci_config_le_t, subsystem_id), 82*a23fd118Syl &about_info->subsys_device); 83*a23fd118Syl 84*a23fd118Syl xge_os_pci_read8(hldev->pdev, hldev->cfgh, 85*a23fd118Syl xge_offsetof(xge_hal_pci_config_le_t, revision), 86*a23fd118Syl &about_info->board_rev); 87*a23fd118Syl 88*a23fd118Syl xge_os_strcpy(about_info->vendor_name, XGE_DRIVER_VENDOR); 89*a23fd118Syl xge_os_strcpy(about_info->chip_name, XGE_CHIP_FAMILY); 90*a23fd118Syl xge_os_strcpy(about_info->media, XGE_SUPPORTED_MEDIA_0); 91*a23fd118Syl 92*a23fd118Syl xge_os_strcpy(about_info->hal_major, XGE_HAL_VERSION_MAJOR); 93*a23fd118Syl xge_os_strcpy(about_info->hal_minor, XGE_HAL_VERSION_MINOR); 94*a23fd118Syl xge_os_strcpy(about_info->hal_fix, XGE_HAL_VERSION_FIX); 95*a23fd118Syl xge_os_strcpy(about_info->hal_build, XGE_HAL_VERSION_BUILD); 96*a23fd118Syl 97*a23fd118Syl xge_os_strcpy(about_info->ll_major, XGELL_VERSION_MAJOR); 98*a23fd118Syl xge_os_strcpy(about_info->ll_minor, XGELL_VERSION_MINOR); 99*a23fd118Syl xge_os_strcpy(about_info->ll_fix, XGELL_VERSION_FIX); 100*a23fd118Syl xge_os_strcpy(about_info->ll_build, XGELL_VERSION_BUILD); 101*a23fd118Syl 102*a23fd118Syl return XGE_HAL_OK; 103*a23fd118Syl } 104*a23fd118Syl 105*a23fd118Syl /** 106*a23fd118Syl * xge_hal_mgmt_reg_read - Read Xframe register. 107*a23fd118Syl * @devh: HAL device handle. 108*a23fd118Syl * @bar_id: 0 - for BAR0, 1- for BAR1. 109*a23fd118Syl * @offset: Register offset in the Base Address Register (BAR) space. 110*a23fd118Syl * @value: Register value. Returned by HAL. 111*a23fd118Syl * Read Xframe register. 112*a23fd118Syl * 113*a23fd118Syl * Returns: XGE_HAL_OK - success. 114*a23fd118Syl * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid. 115*a23fd118Syl * XGE_HAL_ERR_INVALID_OFFSET - Register offset in the BAR space is not 116*a23fd118Syl * valid. 117*a23fd118Syl * XGE_HAL_ERR_INVALID_BAR_ID - BAR id is not valid. 118*a23fd118Syl * 119*a23fd118Syl * See also: xge_hal_aux_bar0_read(), xge_hal_aux_bar1_read(). 120*a23fd118Syl */ 121*a23fd118Syl xge_hal_status_e 122*a23fd118Syl xge_hal_mgmt_reg_read(xge_hal_device_h devh, int bar_id, unsigned int offset, 123*a23fd118Syl u64 *value) 124*a23fd118Syl { 125*a23fd118Syl xge_hal_device_t *hldev = (xge_hal_device_t*)devh; 126*a23fd118Syl 127*a23fd118Syl if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) { 128*a23fd118Syl return XGE_HAL_ERR_INVALID_DEVICE; 129*a23fd118Syl } 130*a23fd118Syl 131*a23fd118Syl if (bar_id == 0) { 132*a23fd118Syl if (offset > sizeof(xge_hal_pci_bar0_t)-8) { 133*a23fd118Syl return XGE_HAL_ERR_INVALID_OFFSET; 134*a23fd118Syl } 135*a23fd118Syl *value = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0, 136*a23fd118Syl (void *)(hldev->bar0 + offset)); 137*a23fd118Syl } else if (bar_id == 1) { 138*a23fd118Syl int i; 139*a23fd118Syl for (i=0; i<XGE_HAL_MAX_FIFO_NUM; i++) { 140*a23fd118Syl if (offset == i*0x2000 || offset == i*0x2000+0x18) { 141*a23fd118Syl break; 142*a23fd118Syl } 143*a23fd118Syl } 144*a23fd118Syl if (i == XGE_HAL_MAX_FIFO_NUM) { 145*a23fd118Syl return XGE_HAL_ERR_INVALID_OFFSET; 146*a23fd118Syl } 147*a23fd118Syl *value = xge_os_pio_mem_read64(hldev->pdev, hldev->regh1, 148*a23fd118Syl (void *)(hldev->bar1 + offset)); 149*a23fd118Syl } else { 150*a23fd118Syl return XGE_HAL_ERR_INVALID_BAR_ID; 151*a23fd118Syl } 152*a23fd118Syl 153*a23fd118Syl return XGE_HAL_OK; 154*a23fd118Syl } 155*a23fd118Syl 156*a23fd118Syl /** 157*a23fd118Syl * xge_hal_mgmt_reg_write - Write Xframe register. 158*a23fd118Syl * @devh: HAL device handle. 159*a23fd118Syl * @bar_id: 0 - for BAR0, 1- for BAR1. 160*a23fd118Syl * @offset: Register offset in the Base Address Register (BAR) space. 161*a23fd118Syl * @value: Register value. 162*a23fd118Syl * 163*a23fd118Syl * Write Xframe register. 164*a23fd118Syl * 165*a23fd118Syl * Returns: XGE_HAL_OK - success. 166*a23fd118Syl * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid. 167*a23fd118Syl * XGE_HAL_ERR_INVALID_OFFSET - Register offset in the BAR space is not 168*a23fd118Syl * valid. 169*a23fd118Syl * XGE_HAL_ERR_INVALID_BAR_ID - BAR id is not valid. 170*a23fd118Syl * 171*a23fd118Syl * See also: xge_hal_aux_bar0_write(). 172*a23fd118Syl */ 173*a23fd118Syl xge_hal_status_e 174*a23fd118Syl xge_hal_mgmt_reg_write(xge_hal_device_h devh, int bar_id, unsigned int offset, 175*a23fd118Syl u64 value) 176*a23fd118Syl { 177*a23fd118Syl xge_hal_device_t *hldev = (xge_hal_device_t*)devh; 178*a23fd118Syl 179*a23fd118Syl if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) { 180*a23fd118Syl return XGE_HAL_ERR_INVALID_DEVICE; 181*a23fd118Syl } 182*a23fd118Syl 183*a23fd118Syl if (bar_id == 0) { 184*a23fd118Syl if (offset > sizeof(xge_hal_pci_bar0_t)-8) { 185*a23fd118Syl return XGE_HAL_ERR_INVALID_OFFSET; 186*a23fd118Syl } 187*a23fd118Syl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, value, 188*a23fd118Syl (void *)(hldev->bar0 + offset)); 189*a23fd118Syl } else if (bar_id == 1) { 190*a23fd118Syl int i; 191*a23fd118Syl for (i=0; i<XGE_HAL_MAX_FIFO_NUM; i++) { 192*a23fd118Syl if (offset == i*0x2000 || offset == i*0x2000+0x18) { 193*a23fd118Syl break; 194*a23fd118Syl } 195*a23fd118Syl } 196*a23fd118Syl if (i == XGE_HAL_MAX_FIFO_NUM) { 197*a23fd118Syl return XGE_HAL_ERR_INVALID_OFFSET; 198*a23fd118Syl } 199*a23fd118Syl xge_os_pio_mem_write64(hldev->pdev, hldev->regh1, value, 200*a23fd118Syl (void *)(hldev->bar1 + offset)); 201*a23fd118Syl } else { 202*a23fd118Syl return XGE_HAL_ERR_INVALID_BAR_ID; 203*a23fd118Syl } 204*a23fd118Syl 205*a23fd118Syl return XGE_HAL_OK; 206*a23fd118Syl } 207*a23fd118Syl 208*a23fd118Syl /** 209*a23fd118Syl * xge_hal_mgmt_hw_stats - Get Xframe hardware statistics. 210*a23fd118Syl * @devh: HAL device handle. 211*a23fd118Syl * @hw_stats: Hardware statistics. Returned by HAL. 212*a23fd118Syl * See xge_hal_stats_hw_info_t{}. 213*a23fd118Syl * @size: Size of the @hw_stats buffer. HAL will return an error 214*a23fd118Syl * if the size is smaller than sizeof(xge_hal_stats_hw_info_t). 215*a23fd118Syl * Get Xframe hardware statistics. 216*a23fd118Syl * 217*a23fd118Syl * Returns: XGE_HAL_OK - success. 218*a23fd118Syl * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid. 219*a23fd118Syl * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching. 220*a23fd118Syl * 221*a23fd118Syl * See also: xge_hal_mgmt_sw_stats(). 222*a23fd118Syl */ 223*a23fd118Syl xge_hal_status_e 224*a23fd118Syl xge_hal_mgmt_hw_stats(xge_hal_device_h devh, xge_hal_mgmt_hw_stats_t *hw_stats, 225*a23fd118Syl int size) 226*a23fd118Syl { 227*a23fd118Syl xge_hal_status_e status; 228*a23fd118Syl xge_hal_device_t *hldev = (xge_hal_device_t*)devh; 229*a23fd118Syl xge_hal_stats_hw_info_t *hw_info; 230*a23fd118Syl 231*a23fd118Syl if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) { 232*a23fd118Syl return XGE_HAL_ERR_INVALID_DEVICE; 233*a23fd118Syl } 234*a23fd118Syl 235*a23fd118Syl if (size != sizeof(xge_hal_stats_hw_info_t)) { 236*a23fd118Syl return XGE_HAL_ERR_VERSION_CONFLICT; 237*a23fd118Syl } 238*a23fd118Syl 239*a23fd118Syl if ((status = xge_hal_stats_hw (devh, &hw_info)) != XGE_HAL_OK) { 240*a23fd118Syl return status; 241*a23fd118Syl } 242*a23fd118Syl 243*a23fd118Syl xge_os_memcpy(hw_stats, hw_info, sizeof(xge_hal_stats_hw_info_t)); 244*a23fd118Syl 245*a23fd118Syl return XGE_HAL_OK; 246*a23fd118Syl } 247*a23fd118Syl 248*a23fd118Syl /** 249*a23fd118Syl * FIXME: document 250*a23fd118Syl */ 251*a23fd118Syl xge_hal_status_e 252*a23fd118Syl xge_hal_mgmt_hw_stats_off(xge_hal_device_h devh, int off, int size, char *out) 253*a23fd118Syl { 254*a23fd118Syl xge_hal_status_e status; 255*a23fd118Syl xge_hal_device_t *hldev = (xge_hal_device_t*)devh; 256*a23fd118Syl xge_hal_stats_hw_info_t *hw_info; 257*a23fd118Syl 258*a23fd118Syl if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) { 259*a23fd118Syl return XGE_HAL_ERR_INVALID_DEVICE; 260*a23fd118Syl } 261*a23fd118Syl 262*a23fd118Syl if (off > sizeof(xge_hal_stats_hw_info_t)-4 || 263*a23fd118Syl size > 8) { 264*a23fd118Syl return XGE_HAL_ERR_INVALID_OFFSET; 265*a23fd118Syl } 266*a23fd118Syl 267*a23fd118Syl if ((status = xge_hal_stats_hw (devh, &hw_info)) != XGE_HAL_OK) { 268*a23fd118Syl return status; 269*a23fd118Syl } 270*a23fd118Syl 271*a23fd118Syl xge_os_memcpy(out, (char*)hw_info + off, size); 272*a23fd118Syl 273*a23fd118Syl return XGE_HAL_OK; 274*a23fd118Syl } 275*a23fd118Syl 276*a23fd118Syl /** 277*a23fd118Syl * xge_hal_mgmt_sw_stats - Get per-device software statistics. 278*a23fd118Syl * @devh: HAL device handle. 279*a23fd118Syl * @sw_stats: Hardware statistics. Returned by HAL. 280*a23fd118Syl * See xge_hal_stats_sw_err_t{}. 281*a23fd118Syl * @size: Size of the @sw_stats buffer. HAL will return an error 282*a23fd118Syl * if the size is smaller than sizeof(xge_hal_stats_sw_err_t). 283*a23fd118Syl * Get device software statistics, including ECC and Parity error 284*a23fd118Syl * counters, etc. 285*a23fd118Syl * 286*a23fd118Syl * Returns: XGE_HAL_OK - success. 287*a23fd118Syl * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid. 288*a23fd118Syl * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching. 289*a23fd118Syl * 290*a23fd118Syl * See also: xge_hal_stats_sw_err_t{}, xge_hal_mgmt_hw_stats(). 291*a23fd118Syl */ 292*a23fd118Syl xge_hal_status_e 293*a23fd118Syl xge_hal_mgmt_sw_stats(xge_hal_device_h devh, xge_hal_mgmt_sw_stats_t *sw_stats, 294*a23fd118Syl int size) 295*a23fd118Syl { 296*a23fd118Syl xge_hal_device_t *hldev = (xge_hal_device_t*)devh; 297*a23fd118Syl 298*a23fd118Syl if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) { 299*a23fd118Syl return XGE_HAL_ERR_INVALID_DEVICE; 300*a23fd118Syl } 301*a23fd118Syl 302*a23fd118Syl if (size != sizeof(xge_hal_stats_sw_err_t)) { 303*a23fd118Syl return XGE_HAL_ERR_VERSION_CONFLICT; 304*a23fd118Syl } 305*a23fd118Syl 306*a23fd118Syl if (!hldev->stats.is_initialized || 307*a23fd118Syl !hldev->stats.is_enabled) { 308*a23fd118Syl return XGE_HAL_INF_STATS_IS_NOT_READY; 309*a23fd118Syl } 310*a23fd118Syl 311*a23fd118Syl xge_os_memcpy(sw_stats, &hldev->stats.sw_dev_err_stats, 312*a23fd118Syl sizeof(xge_hal_stats_sw_err_t)); 313*a23fd118Syl 314*a23fd118Syl return XGE_HAL_OK; 315*a23fd118Syl } 316*a23fd118Syl 317*a23fd118Syl /** 318*a23fd118Syl * xge_hal_mgmt_device_stats - Get HAL device statistics. 319*a23fd118Syl * @devh: HAL device handle. 320*a23fd118Syl * @device_stats: HAL device "soft" statistics. Maintained by HAL itself. 321*a23fd118Syl * (as opposed to xge_hal_mgmt_hw_stats() - those are 322*a23fd118Syl * maintained by the Xframe hardware). 323*a23fd118Syl * Returned by HAL. 324*a23fd118Syl * See xge_hal_stats_device_info_t{}. 325*a23fd118Syl * @size: Size of the @device_stats buffer. HAL will return an error 326*a23fd118Syl * if the size is smaller than sizeof(xge_hal_stats_device_info_t). 327*a23fd118Syl * 328*a23fd118Syl * Get HAL (layer) statistic counters. 329*a23fd118Syl * Returns: XGE_HAL_OK - success. 330*a23fd118Syl * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid. 331*a23fd118Syl * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching. 332*a23fd118Syl * XGE_HAL_INF_STATS_IS_NOT_READY - Statistics information is not 333*a23fd118Syl * currently available. 334*a23fd118Syl * 335*a23fd118Syl */ 336*a23fd118Syl xge_hal_status_e 337*a23fd118Syl xge_hal_mgmt_device_stats(xge_hal_device_h devh, 338*a23fd118Syl xge_hal_mgmt_device_stats_t *device_stats, int size) 339*a23fd118Syl { 340*a23fd118Syl xge_hal_status_e status; 341*a23fd118Syl xge_hal_device_t *hldev = (xge_hal_device_t*)devh; 342*a23fd118Syl xge_hal_stats_device_info_t *device_info; 343*a23fd118Syl 344*a23fd118Syl if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) { 345*a23fd118Syl return XGE_HAL_ERR_INVALID_DEVICE; 346*a23fd118Syl } 347*a23fd118Syl 348*a23fd118Syl if (size != sizeof(xge_hal_stats_device_info_t)) { 349*a23fd118Syl return XGE_HAL_ERR_VERSION_CONFLICT; 350*a23fd118Syl } 351*a23fd118Syl 352*a23fd118Syl if ((status = xge_hal_stats_device (devh, &device_info)) != 353*a23fd118Syl XGE_HAL_OK) { 354*a23fd118Syl return status; 355*a23fd118Syl } 356*a23fd118Syl 357*a23fd118Syl xge_os_memcpy(device_stats, device_info, 358*a23fd118Syl sizeof(xge_hal_stats_device_info_t)); 359*a23fd118Syl 360*a23fd118Syl return XGE_HAL_OK; 361*a23fd118Syl } 362*a23fd118Syl 363*a23fd118Syl /* 364*a23fd118Syl * __hal_update_ring_bump - Update the ring bump counter for the 365*a23fd118Syl * particular channel. 366*a23fd118Syl * @hldev: HAL device handle. 367*a23fd118Syl * @queue: the queue who's data is to be collected. 368*a23fd118Syl * @chinfo: pointer to the statistics structure of the given channel. 369*a23fd118Syl * Usage: See xge_hal_aux_stats_hal_read{} 370*a23fd118Syl */ 371*a23fd118Syl 372*a23fd118Syl static void 373*a23fd118Syl __hal_update_ring_bump(xge_hal_device_t *hldev, int queue, 374*a23fd118Syl xge_hal_stats_channel_info_t *chinfo) 375*a23fd118Syl { 376*a23fd118Syl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0; 377*a23fd118Syl u64 rbc = 0; 378*a23fd118Syl int reg = (queue / 4); 379*a23fd118Syl void * addr; 380*a23fd118Syl 381*a23fd118Syl addr = (reg == 1)? (&bar0->ring_bump_counter2) : 382*a23fd118Syl (&bar0->ring_bump_counter1); 383*a23fd118Syl rbc = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0, addr); 384*a23fd118Syl chinfo->ring_bump_cnt = XGE_HAL_RING_BUMP_CNT(queue, rbc); 385*a23fd118Syl } 386*a23fd118Syl 387*a23fd118Syl /** 388*a23fd118Syl * xge_hal_mgmt_channel_stats - Get HAL channel statistics. 389*a23fd118Syl * @channelh: HAL channel handle. 390*a23fd118Syl * @channel_stats: HAL channel statistics. Maintained by HAL itself 391*a23fd118Syl * (as opposed to xge_hal_mgmt_hw_stats() - those are 392*a23fd118Syl * maintained by the Xframe hardware). 393*a23fd118Syl * Returned by HAL. 394*a23fd118Syl * See xge_hal_stats_channel_info_t{}. 395*a23fd118Syl * @size: Size of the @channel_stats buffer. HAL will return an error 396*a23fd118Syl * if the size is smaller than sizeof(xge_hal_mgmt_channel_stats_t). 397*a23fd118Syl * 398*a23fd118Syl * Get HAL per-channel statistic counters. 399*a23fd118Syl * 400*a23fd118Syl * Returns: XGE_HAL_OK - success. 401*a23fd118Syl * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching. 402*a23fd118Syl * XGE_HAL_INF_STATS_IS_NOT_READY - Statistics information is not 403*a23fd118Syl * currently available. 404*a23fd118Syl * 405*a23fd118Syl */ 406*a23fd118Syl xge_hal_status_e 407*a23fd118Syl xge_hal_mgmt_channel_stats(xge_hal_channel_h channelh, 408*a23fd118Syl xge_hal_mgmt_channel_stats_t *channel_stats, int size) 409*a23fd118Syl { 410*a23fd118Syl xge_hal_status_e status; 411*a23fd118Syl xge_hal_stats_channel_info_t *channel_info; 412*a23fd118Syl xge_hal_channel_t *channel = channelh; 413*a23fd118Syl 414*a23fd118Syl if (size != sizeof(xge_hal_stats_channel_info_t)) { 415*a23fd118Syl return XGE_HAL_ERR_VERSION_CONFLICT; 416*a23fd118Syl } 417*a23fd118Syl 418*a23fd118Syl if ((status = xge_hal_stats_channel (channelh, &channel_info)) != 419*a23fd118Syl XGE_HAL_OK) { 420*a23fd118Syl return status; 421*a23fd118Syl } 422*a23fd118Syl 423*a23fd118Syl if (xge_hal_device_check_id(channel->devh) == XGE_HAL_CARD_HERC) { 424*a23fd118Syl __hal_update_ring_bump(channel->devh, channel->post_qid, 425*a23fd118Syl channel_info); 426*a23fd118Syl } 427*a23fd118Syl 428*a23fd118Syl xge_os_memcpy(channel_stats, channel_info, 429*a23fd118Syl sizeof(xge_hal_stats_channel_info_t)); 430*a23fd118Syl 431*a23fd118Syl return XGE_HAL_OK; 432*a23fd118Syl } 433*a23fd118Syl 434*a23fd118Syl /** 435*a23fd118Syl * xge_hal_mgmt_pcireg_read - Read PCI configuration at a specified 436*a23fd118Syl * offset. 437*a23fd118Syl * @devh: HAL device handle. 438*a23fd118Syl * @offset: Offset in the 256 byte PCI configuration space. 439*a23fd118Syl * @value_bits: 8, 16, or 32 (bits) to read. 440*a23fd118Syl * @value: Value returned by HAL. 441*a23fd118Syl * 442*a23fd118Syl * Read PCI configuration, given device and offset in the PCI space. 443*a23fd118Syl * 444*a23fd118Syl * Returns: XGE_HAL_OK - success. 445*a23fd118Syl * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid. 446*a23fd118Syl * XGE_HAL_ERR_INVALID_OFFSET - Register offset in the BAR space is not 447*a23fd118Syl * valid. 448*a23fd118Syl * XGE_HAL_ERR_INVALID_VALUE_BIT_SIZE - Invalid bits size. Valid 449*a23fd118Syl * values(8/16/32). 450*a23fd118Syl * 451*a23fd118Syl */ 452*a23fd118Syl xge_hal_status_e 453*a23fd118Syl xge_hal_mgmt_pcireg_read(xge_hal_device_h devh, unsigned int offset, 454*a23fd118Syl int value_bits, u32 *value) 455*a23fd118Syl { 456*a23fd118Syl xge_hal_device_t *hldev = (xge_hal_device_t*)devh; 457*a23fd118Syl 458*a23fd118Syl if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) { 459*a23fd118Syl return XGE_HAL_ERR_INVALID_DEVICE; 460*a23fd118Syl } 461*a23fd118Syl 462*a23fd118Syl if (offset > sizeof(xge_hal_pci_config_t)-value_bits/8) { 463*a23fd118Syl return XGE_HAL_ERR_INVALID_OFFSET; 464*a23fd118Syl } 465*a23fd118Syl 466*a23fd118Syl if (value_bits == 8) { 467*a23fd118Syl xge_os_pci_read8(hldev->pdev, hldev->cfgh, offset, (u8*)value); 468*a23fd118Syl } else if (value_bits == 16) { 469*a23fd118Syl xge_os_pci_read16(hldev->pdev, hldev->cfgh, offset, 470*a23fd118Syl (u16*)value); 471*a23fd118Syl } else if (value_bits == 32) { 472*a23fd118Syl xge_os_pci_read32(hldev->pdev, hldev->cfgh, offset, value); 473*a23fd118Syl } else { 474*a23fd118Syl return XGE_HAL_ERR_INVALID_VALUE_BIT_SIZE; 475*a23fd118Syl } 476*a23fd118Syl 477*a23fd118Syl return XGE_HAL_OK; 478*a23fd118Syl } 479*a23fd118Syl 480*a23fd118Syl /** 481*a23fd118Syl * xge_hal_mgmt_device_config - Retrieve device configuration. 482*a23fd118Syl * @devh: HAL device handle. 483*a23fd118Syl * @dev_config: Device configuration, see xge_hal_device_config_t{}. 484*a23fd118Syl * @size: Size of the @dev_config buffer. HAL will return an error 485*a23fd118Syl * if the size is smaller than sizeof(xge_hal_mgmt_device_config_t). 486*a23fd118Syl * 487*a23fd118Syl * Get device configuration. Permits to retrieve at run-time configuration 488*a23fd118Syl * values that were used to initialize and configure the device. 489*a23fd118Syl * 490*a23fd118Syl * Returns: XGE_HAL_OK - success. 491*a23fd118Syl * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid. 492*a23fd118Syl * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching. 493*a23fd118Syl * 494*a23fd118Syl * See also: xge_hal_device_config_t{}, xge_hal_mgmt_driver_config(). 495*a23fd118Syl */ 496*a23fd118Syl xge_hal_status_e 497*a23fd118Syl xge_hal_mgmt_device_config(xge_hal_device_h devh, 498*a23fd118Syl xge_hal_mgmt_device_config_t *dev_config, int size) 499*a23fd118Syl { 500*a23fd118Syl xge_hal_device_t *hldev = (xge_hal_device_t*)devh; 501*a23fd118Syl 502*a23fd118Syl if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) { 503*a23fd118Syl return XGE_HAL_ERR_INVALID_DEVICE; 504*a23fd118Syl } 505*a23fd118Syl 506*a23fd118Syl if (size != sizeof(xge_hal_mgmt_device_config_t)) { 507*a23fd118Syl return XGE_HAL_ERR_VERSION_CONFLICT; 508*a23fd118Syl } 509*a23fd118Syl 510*a23fd118Syl xge_os_memcpy(dev_config, &hldev->config, 511*a23fd118Syl sizeof(xge_hal_device_config_t)); 512*a23fd118Syl 513*a23fd118Syl return XGE_HAL_OK; 514*a23fd118Syl } 515*a23fd118Syl 516*a23fd118Syl /** 517*a23fd118Syl * xge_hal_mgmt_driver_config - Retrieve driver configuration. 518*a23fd118Syl * @drv_config: Device configuration, see xge_hal_driver_config_t{}. 519*a23fd118Syl * @size: Size of the @dev_config buffer. HAL will return an error 520*a23fd118Syl * if the size is smaller than sizeof(xge_hal_mgmt_driver_config_t). 521*a23fd118Syl * 522*a23fd118Syl * Get driver configuration. Permits to retrieve at run-time configuration 523*a23fd118Syl * values that were used to configure the device at load-time. 524*a23fd118Syl * 525*a23fd118Syl * Returns: XGE_HAL_OK - success. 526*a23fd118Syl * XGE_HAL_ERR_DRIVER_NOT_INITIALIZED - HAL is not initialized. 527*a23fd118Syl * XGE_HAL_ERR_VERSION_CONFLICT - Version is not maching. 528*a23fd118Syl * 529*a23fd118Syl * See also: xge_hal_driver_config_t{}, xge_hal_mgmt_device_config(). 530*a23fd118Syl */ 531*a23fd118Syl xge_hal_status_e 532*a23fd118Syl xge_hal_mgmt_driver_config(xge_hal_mgmt_driver_config_t *drv_config, int size) 533*a23fd118Syl { 534*a23fd118Syl 535*a23fd118Syl if (g_xge_hal_driver == NULL) { 536*a23fd118Syl return XGE_HAL_ERR_DRIVER_NOT_INITIALIZED; 537*a23fd118Syl } 538*a23fd118Syl 539*a23fd118Syl if (size != sizeof(xge_hal_mgmt_driver_config_t)) { 540*a23fd118Syl return XGE_HAL_ERR_VERSION_CONFLICT; 541*a23fd118Syl } 542*a23fd118Syl 543*a23fd118Syl xge_os_memcpy(drv_config, &g_xge_hal_driver->config, 544*a23fd118Syl sizeof(xge_hal_mgmt_driver_config_t)); 545*a23fd118Syl 546*a23fd118Syl return XGE_HAL_OK; 547*a23fd118Syl } 548*a23fd118Syl 549*a23fd118Syl /** 550*a23fd118Syl * xge_hal_mgmt_pci_config - Retrieve PCI configuration. 551*a23fd118Syl * @devh: HAL device handle. 552*a23fd118Syl * @pci_config: 256 byte long buffer for PCI configuration space. 553*a23fd118Syl * @size: Size of the @ buffer. HAL will return an error 554*a23fd118Syl * if the size is smaller than sizeof(xge_hal_mgmt_pci_config_t). 555*a23fd118Syl * 556*a23fd118Syl * Get PCI configuration. Permits to retrieve at run-time configuration 557*a23fd118Syl * values that were used to configure the device at load-time. 558*a23fd118Syl * 559*a23fd118Syl * Returns: XGE_HAL_OK - success. 560*a23fd118Syl * XGE_HAL_ERR_INVALID_DEVICE - Device is not valid. 561*a23fd118Syl * XGE_HAL_ERR_VERSION_CONFLICT - Version it not maching. 562*a23fd118Syl * 563*a23fd118Syl */ 564*a23fd118Syl xge_hal_status_e 565*a23fd118Syl xge_hal_mgmt_pci_config(xge_hal_device_h devh, 566*a23fd118Syl xge_hal_mgmt_pci_config_t *pci_config, int size) 567*a23fd118Syl { 568*a23fd118Syl int i; 569*a23fd118Syl xge_hal_device_t *hldev = (xge_hal_device_t*)devh; 570*a23fd118Syl 571*a23fd118Syl if ((hldev == NULL) || (hldev->magic != XGE_HAL_MAGIC)) { 572*a23fd118Syl return XGE_HAL_ERR_INVALID_DEVICE; 573*a23fd118Syl } 574*a23fd118Syl 575*a23fd118Syl if (size != sizeof(xge_hal_mgmt_pci_config_t)) { 576*a23fd118Syl return XGE_HAL_ERR_VERSION_CONFLICT; 577*a23fd118Syl } 578*a23fd118Syl 579*a23fd118Syl /* refresh PCI config space */ 580*a23fd118Syl for (i = 0; i < 0x68/4+1; i++) { 581*a23fd118Syl xge_os_pci_read32(hldev->pdev, hldev->cfgh, i*4, 582*a23fd118Syl (u32*)&hldev->pci_config_space + i); 583*a23fd118Syl } 584*a23fd118Syl 585*a23fd118Syl xge_os_memcpy(pci_config, &hldev->pci_config_space, 586*a23fd118Syl sizeof(xge_hal_mgmt_pci_config_t)); 587*a23fd118Syl 588*a23fd118Syl return XGE_HAL_OK; 589*a23fd118Syl } 590*a23fd118Syl 591*a23fd118Syl #ifdef XGE_TRACE_INTO_CIRCULAR_ARR 592*a23fd118Syl /** 593*a23fd118Syl * xge_hal_mgmt_trace_read - Read trace buffer contents. 594*a23fd118Syl * @buffer: Buffer to store the trace buffer contents. 595*a23fd118Syl * @buf_size: Size of the buffer. 596*a23fd118Syl * @offset: Offset in the internal trace buffer to read data. 597*a23fd118Syl * @read_length: Size of the valid data in the buffer. 598*a23fd118Syl * 599*a23fd118Syl * Read HAL trace buffer contents starting from the offset 600*a23fd118Syl * upto the size of the buffer or till EOF is reached. 601*a23fd118Syl * 602*a23fd118Syl * Returns: XGE_HAL_OK - success. 603*a23fd118Syl * XGE_HAL_EOF_TRACE_BUF - No more data in the trace buffer. 604*a23fd118Syl * 605*a23fd118Syl */ 606*a23fd118Syl xge_hal_status_e 607*a23fd118Syl xge_hal_mgmt_trace_read (char *buffer, 608*a23fd118Syl unsigned buf_size, 609*a23fd118Syl unsigned *offset, 610*a23fd118Syl unsigned *read_length) 611*a23fd118Syl { 612*a23fd118Syl int data_offset; 613*a23fd118Syl int start_offset; 614*a23fd118Syl 615*a23fd118Syl if ((g_xge_os_tracebuf == NULL) || 616*a23fd118Syl (g_xge_os_tracebuf->offset == g_xge_os_tracebuf->size - 2)) { 617*a23fd118Syl return XGE_HAL_EOF_TRACE_BUF; 618*a23fd118Syl } 619*a23fd118Syl 620*a23fd118Syl data_offset = g_xge_os_tracebuf->offset + 1; 621*a23fd118Syl 622*a23fd118Syl if (*offset >= (unsigned)xge_os_strlen(g_xge_os_tracebuf->data + 623*a23fd118Syl data_offset)) { 624*a23fd118Syl 625*a23fd118Syl return XGE_HAL_EOF_TRACE_BUF; 626*a23fd118Syl } 627*a23fd118Syl 628*a23fd118Syl xge_os_memzero(buffer, buf_size); 629*a23fd118Syl 630*a23fd118Syl start_offset = data_offset + *offset; 631*a23fd118Syl *read_length = xge_os_strlen(g_xge_os_tracebuf->data + 632*a23fd118Syl start_offset); 633*a23fd118Syl 634*a23fd118Syl if (*read_length >= buf_size) { 635*a23fd118Syl *read_length = buf_size - 1; 636*a23fd118Syl } 637*a23fd118Syl 638*a23fd118Syl xge_os_memcpy(buffer, g_xge_os_tracebuf->data + start_offset, 639*a23fd118Syl *read_length); 640*a23fd118Syl 641*a23fd118Syl *offset += *read_length; 642*a23fd118Syl (*read_length) ++; 643*a23fd118Syl 644*a23fd118Syl return XGE_HAL_OK; 645*a23fd118Syl } 646*a23fd118Syl 647*a23fd118Syl #endif 648*a23fd118Syl 649*a23fd118Syl /** 650*a23fd118Syl * xge_hal_restore_link_led - Restore link LED to its original state. 651*a23fd118Syl * @devh: HAL device handle. 652*a23fd118Syl */ 653*a23fd118Syl void 654*a23fd118Syl xge_hal_restore_link_led(xge_hal_device_h devh) 655*a23fd118Syl { 656*a23fd118Syl xge_hal_device_t *hldev = (xge_hal_device_t*)devh; 657*a23fd118Syl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0; 658*a23fd118Syl u64 val64; 659*a23fd118Syl 660*a23fd118Syl /* 661*a23fd118Syl * If the current link state is UP, switch on LED else make it 662*a23fd118Syl * off. 663*a23fd118Syl */ 664*a23fd118Syl 665*a23fd118Syl /* 666*a23fd118Syl * For Xena 3 and lower revision cards, adapter control needs to be 667*a23fd118Syl * used for making LED ON/OFF. 668*a23fd118Syl */ 669*a23fd118Syl if ((xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA) && 670*a23fd118Syl (xge_hal_device_rev(hldev) <= 3)) { 671*a23fd118Syl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0, 672*a23fd118Syl &bar0->adapter_control); 673*a23fd118Syl if (hldev->link_state == XGE_HAL_LINK_UP) { 674*a23fd118Syl val64 |= XGE_HAL_ADAPTER_LED_ON; 675*a23fd118Syl } else { 676*a23fd118Syl val64 &= ~XGE_HAL_ADAPTER_LED_ON; 677*a23fd118Syl } 678*a23fd118Syl 679*a23fd118Syl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, 680*a23fd118Syl &bar0->adapter_control); 681*a23fd118Syl return; 682*a23fd118Syl } 683*a23fd118Syl 684*a23fd118Syl /* 685*a23fd118Syl * Use beacon control register to control the LED. 686*a23fd118Syl * LED link output corresponds to bit 8 of the beacon control 687*a23fd118Syl * register. Note that, in the case of Xena, beacon control register 688*a23fd118Syl * represents the gpio control register. In the case of Herc, LED 689*a23fd118Syl * handling is done by beacon control register as opposed to gpio 690*a23fd118Syl * control register in Xena. 691*a23fd118Syl */ 692*a23fd118Syl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0, 693*a23fd118Syl &bar0->beacon_control); 694*a23fd118Syl if (hldev->link_state == XGE_HAL_LINK_UP) { 695*a23fd118Syl val64 |= 0x0080800000000000ULL; 696*a23fd118Syl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, 697*a23fd118Syl val64, &bar0->beacon_control); 698*a23fd118Syl } else { 699*a23fd118Syl val64 |= 0x0000800000000000ULL; 700*a23fd118Syl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, 701*a23fd118Syl val64, &bar0->beacon_control); 702*a23fd118Syl } 703*a23fd118Syl } 704*a23fd118Syl 705*a23fd118Syl /** 706*a23fd118Syl * xge_hal_flick_link_led - Flick (blink) link LED. 707*a23fd118Syl * @devh: HAL device handle. 708*a23fd118Syl * 709*a23fd118Syl * Depending on the card revision flicker the link LED by using the 710*a23fd118Syl * beacon control or the adapter_control register. 711*a23fd118Syl */ 712*a23fd118Syl void 713*a23fd118Syl xge_hal_flick_link_led(xge_hal_device_h devh) 714*a23fd118Syl { 715*a23fd118Syl xge_hal_device_t *hldev = (xge_hal_device_t*)devh; 716*a23fd118Syl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0; 717*a23fd118Syl u64 val64 = 0; 718*a23fd118Syl 719*a23fd118Syl /* 720*a23fd118Syl * For Xena 3 and lower revision cards, adapter control needs to be 721*a23fd118Syl * used for making LED ON/OFF. 722*a23fd118Syl */ 723*a23fd118Syl if ((xge_hal_device_check_id(hldev) == XGE_HAL_CARD_XENA) && 724*a23fd118Syl (xge_hal_device_rev(hldev) <= 3)) { 725*a23fd118Syl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0, 726*a23fd118Syl &bar0->adapter_control); 727*a23fd118Syl val64 ^= XGE_HAL_ADAPTER_LED_ON; 728*a23fd118Syl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, 729*a23fd118Syl &bar0->adapter_control); 730*a23fd118Syl return; 731*a23fd118Syl } 732*a23fd118Syl 733*a23fd118Syl /* 734*a23fd118Syl * Use beacon control register to control the Link LED. 735*a23fd118Syl * Note that, in the case of Xena, beacon control register represents 736*a23fd118Syl * the gpio control register. In the case of Herc, LED handling is 737*a23fd118Syl * done by beacon control register as opposed to gpio control register 738*a23fd118Syl * in Xena. 739*a23fd118Syl */ 740*a23fd118Syl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0, 741*a23fd118Syl &bar0->beacon_control); 742*a23fd118Syl val64 ^= XGE_HAL_GPIO_CTRL_GPIO_0; 743*a23fd118Syl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, 744*a23fd118Syl &bar0->beacon_control); 745*a23fd118Syl } 746*a23fd118Syl 747*a23fd118Syl /** 748*a23fd118Syl * xge_hal_read_eeprom - Read 4 bytes of data from user given offset. 749*a23fd118Syl * @devh: HAL device handle. 750*a23fd118Syl * @off: offset at which the data must be written 751*a23fd118Syl * @data: output parameter where the data is stored. 752*a23fd118Syl * 753*a23fd118Syl * Read 4 bytes of data from the user given offset and return the 754*a23fd118Syl * read data. 755*a23fd118Syl * Note: will allow to read only part of the EEPROM visible through the 756*a23fd118Syl * I2C bus. 757*a23fd118Syl * Returns: -1 on failure, 0 on success. 758*a23fd118Syl */ 759*a23fd118Syl xge_hal_status_e 760*a23fd118Syl xge_hal_read_eeprom(xge_hal_device_h devh, xge_hal_status_e off, u32* data) 761*a23fd118Syl { 762*a23fd118Syl xge_hal_device_t *hldev = (xge_hal_device_t*)devh; 763*a23fd118Syl int ret = XGE_HAL_FAIL; 764*a23fd118Syl u32 exit_cnt = 0; 765*a23fd118Syl u64 val64; 766*a23fd118Syl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0; 767*a23fd118Syl 768*a23fd118Syl 769*a23fd118Syl val64 = XGE_HAL_I2C_CONTROL_DEV_ID(XGE_DEV_ID) | 770*a23fd118Syl XGE_HAL_I2C_CONTROL_ADDR(off) | 771*a23fd118Syl XGE_HAL_I2C_CONTROL_BYTE_CNT(0x3) | 772*a23fd118Syl XGE_HAL_I2C_CONTROL_READ | XGE_HAL_I2C_CONTROL_CNTL_START; 773*a23fd118Syl 774*a23fd118Syl __hal_pio_mem_write32_lower(hldev->pdev, hldev->regh0, 775*a23fd118Syl (u32)val64, &bar0->i2c_control); 776*a23fd118Syl __hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0, 777*a23fd118Syl (u32) (val64 >> 32), &bar0->i2c_control); 778*a23fd118Syl 779*a23fd118Syl while (exit_cnt < 5) { 780*a23fd118Syl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0, 781*a23fd118Syl &bar0->i2c_control); 782*a23fd118Syl if (XGE_HAL_I2C_CONTROL_CNTL_END(val64)) { 783*a23fd118Syl *data = XGE_HAL_I2C_CONTROL_GET_DATA(val64); 784*a23fd118Syl ret = XGE_HAL_OK; 785*a23fd118Syl break; 786*a23fd118Syl } 787*a23fd118Syl xge_os_mdelay(50); 788*a23fd118Syl exit_cnt++; 789*a23fd118Syl } 790*a23fd118Syl 791*a23fd118Syl return ret; 792*a23fd118Syl } 793*a23fd118Syl 794*a23fd118Syl /* 795*a23fd118Syl * xge_hal_write_eeprom - actually writes the relevant part of the data 796*a23fd118Syl value. 797*a23fd118Syl * @devh: HAL device handle. 798*a23fd118Syl * @off: offset at which the data must be written 799*a23fd118Syl * @data : The data that is to be written 800*a23fd118Syl * @cnt : Number of bytes of the data that are actually to be written into 801*a23fd118Syl * the Eeprom. (max of 3) 802*a23fd118Syl * 803*a23fd118Syl * Actually writes the relevant part of the data value into the Eeprom 804*a23fd118Syl * through the I2C bus. 805*a23fd118Syl * Return value: 806*a23fd118Syl * 0 on success, -1 on failure. 807*a23fd118Syl */ 808*a23fd118Syl 809*a23fd118Syl xge_hal_status_e 810*a23fd118Syl xge_hal_write_eeprom(xge_hal_device_h devh, int off, u32 data, int cnt) 811*a23fd118Syl { 812*a23fd118Syl xge_hal_device_t *hldev = (xge_hal_device_t*)devh; 813*a23fd118Syl int exit_cnt = 0, ret = XGE_HAL_FAIL; 814*a23fd118Syl u64 val64; 815*a23fd118Syl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0; 816*a23fd118Syl 817*a23fd118Syl val64 = XGE_HAL_I2C_CONTROL_DEV_ID(XGE_DEV_ID) | 818*a23fd118Syl XGE_HAL_I2C_CONTROL_ADDR(off) | 819*a23fd118Syl XGE_HAL_I2C_CONTROL_BYTE_CNT(cnt) | 820*a23fd118Syl XGE_HAL_I2C_CONTROL_SET_DATA(data) | 821*a23fd118Syl XGE_HAL_I2C_CONTROL_CNTL_START; 822*a23fd118Syl __hal_pio_mem_write32_lower(hldev->pdev, hldev->regh0, 823*a23fd118Syl (u32)val64, &bar0->i2c_control); 824*a23fd118Syl __hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0, 825*a23fd118Syl (u32) (val64 >> 32), &bar0->i2c_control); 826*a23fd118Syl 827*a23fd118Syl while (exit_cnt < 5) { 828*a23fd118Syl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0, 829*a23fd118Syl &bar0->i2c_control); 830*a23fd118Syl if (XGE_HAL_I2C_CONTROL_CNTL_END(val64)) { 831*a23fd118Syl if (!(val64 & XGE_HAL_I2C_CONTROL_NACK)) 832*a23fd118Syl ret = XGE_HAL_OK; 833*a23fd118Syl break; 834*a23fd118Syl } 835*a23fd118Syl xge_os_mdelay(50); 836*a23fd118Syl exit_cnt++; 837*a23fd118Syl } 838*a23fd118Syl 839*a23fd118Syl return ret; 840*a23fd118Syl } 841*a23fd118Syl 842*a23fd118Syl /* 843*a23fd118Syl * xge_hal_register_test - reads and writes into all clock domains. 844*a23fd118Syl * @hldev : private member of the device structure. 845*a23fd118Syl * xge_nic structure. 846*a23fd118Syl * @data : variable that returns the result of each of the test conducted b 847*a23fd118Syl * by the driver. 848*a23fd118Syl * 849*a23fd118Syl * Read and write into all clock domains. The NIC has 3 clock domains, 850*a23fd118Syl * see that registers in all the three regions are accessible. 851*a23fd118Syl * Return value: 852*a23fd118Syl * 0 on success. 853*a23fd118Syl */ 854*a23fd118Syl xge_hal_status_e 855*a23fd118Syl xge_hal_register_test(xge_hal_device_h devh, u64 *data) 856*a23fd118Syl { 857*a23fd118Syl xge_hal_device_t *hldev = (xge_hal_device_t*)devh; 858*a23fd118Syl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0; 859*a23fd118Syl u64 val64 = 0; 860*a23fd118Syl int fail = 0; 861*a23fd118Syl 862*a23fd118Syl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0, 863*a23fd118Syl &bar0->pif_rd_swapper_fb); 864*a23fd118Syl if (val64 != 0x123456789abcdefULL) { 865*a23fd118Syl fail = 1; 866*a23fd118Syl xge_debug_osdep(XGE_TRACE, "Read Test level 1 fails\n"); 867*a23fd118Syl } 868*a23fd118Syl 869*a23fd118Syl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0, 870*a23fd118Syl &bar0->rmac_pause_cfg); 871*a23fd118Syl if (val64 != 0xc000ffff00000000ULL) { 872*a23fd118Syl fail = 1; 873*a23fd118Syl xge_debug_osdep(XGE_TRACE, "Read Test level 2 fails\n"); 874*a23fd118Syl } 875*a23fd118Syl 876*a23fd118Syl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0, 877*a23fd118Syl &bar0->rx_queue_cfg); 878*a23fd118Syl if (val64 != 0x0808080808080808ULL) { 879*a23fd118Syl fail = 1; 880*a23fd118Syl xge_debug_osdep(XGE_TRACE, "Read Test level 3 fails\n"); 881*a23fd118Syl } 882*a23fd118Syl 883*a23fd118Syl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0, 884*a23fd118Syl &bar0->xgxs_efifo_cfg); 885*a23fd118Syl if (val64 != 0x000000001923141EULL) { 886*a23fd118Syl fail = 1; 887*a23fd118Syl xge_debug_osdep(XGE_TRACE, "Read Test level 4 fails\n"); 888*a23fd118Syl } 889*a23fd118Syl 890*a23fd118Syl val64 = 0x5A5A5A5A5A5A5A5AULL; 891*a23fd118Syl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, 892*a23fd118Syl &bar0->xmsi_data); 893*a23fd118Syl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0, 894*a23fd118Syl &bar0->xmsi_data); 895*a23fd118Syl if (val64 != 0x5A5A5A5A5A5A5A5AULL) { 896*a23fd118Syl fail = 1; 897*a23fd118Syl xge_debug_osdep(XGE_ERR, "Write Test level 1 fails\n"); 898*a23fd118Syl } 899*a23fd118Syl 900*a23fd118Syl val64 = 0xA5A5A5A5A5A5A5A5ULL; 901*a23fd118Syl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, 902*a23fd118Syl &bar0->xmsi_data); 903*a23fd118Syl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0, 904*a23fd118Syl &bar0->xmsi_data); 905*a23fd118Syl if (val64 != 0xA5A5A5A5A5A5A5A5ULL) { 906*a23fd118Syl fail = 1; 907*a23fd118Syl xge_debug_osdep(XGE_ERR, "Write Test level 2 fails\n"); 908*a23fd118Syl } 909*a23fd118Syl 910*a23fd118Syl *data = fail; 911*a23fd118Syl return XGE_HAL_OK; 912*a23fd118Syl } 913*a23fd118Syl 914*a23fd118Syl /* 915*a23fd118Syl * xge_hal_rldram_test - offline test for access to the RldRam chip on 916*a23fd118Syl the NIC 917*a23fd118Syl * @devh: HAL device handle. 918*a23fd118Syl * @data: variable that returns the result of each of the test 919*a23fd118Syl * conducted by the driver. 920*a23fd118Syl * 921*a23fd118Syl * This is one of the offline test that tests the read and write 922*a23fd118Syl * access to the RldRam chip on the NIC. 923*a23fd118Syl * Return value: 924*a23fd118Syl * 0 on success. 925*a23fd118Syl */ 926*a23fd118Syl xge_hal_status_e 927*a23fd118Syl xge_hal_rldram_test(xge_hal_device_h devh, uint64_t * data) 928*a23fd118Syl { 929*a23fd118Syl xge_hal_device_t *hldev = (xge_hal_device_t*)devh; 930*a23fd118Syl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0; 931*a23fd118Syl u64 val64; 932*a23fd118Syl int cnt, iteration = 0, test_pass = 0; 933*a23fd118Syl 934*a23fd118Syl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0, 935*a23fd118Syl &bar0->adapter_control); 936*a23fd118Syl val64 &= ~XGE_HAL_ADAPTER_ECC_EN; 937*a23fd118Syl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, 938*a23fd118Syl &bar0->adapter_control); 939*a23fd118Syl 940*a23fd118Syl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0, 941*a23fd118Syl &bar0->mc_rldram_test_ctrl); 942*a23fd118Syl val64 |= XGE_HAL_MC_RLDRAM_TEST_MODE; 943*a23fd118Syl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, 944*a23fd118Syl &bar0->mc_rldram_test_ctrl); 945*a23fd118Syl 946*a23fd118Syl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0, 947*a23fd118Syl &bar0->mc_rldram_mrs); 948*a23fd118Syl val64 |= XGE_HAL_MC_RLDRAM_QUEUE_SIZE_ENABLE; 949*a23fd118Syl __hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0, 950*a23fd118Syl (u32) (val64 >> 32), &bar0->i2c_control); 951*a23fd118Syl __hal_pio_mem_write32_lower(hldev->pdev, hldev->regh0, 952*a23fd118Syl (u32)val64, &bar0->mc_rldram_mrs); 953*a23fd118Syl 954*a23fd118Syl val64 |= XGE_HAL_MC_RLDRAM_MRS_ENABLE; 955*a23fd118Syl __hal_pio_mem_write32_upper(hldev->pdev, hldev->regh0, 956*a23fd118Syl (u32) (val64 >> 32), &bar0->i2c_control); 957*a23fd118Syl __hal_pio_mem_write32_lower(hldev->pdev, hldev->regh0, 958*a23fd118Syl (u32)val64, &bar0->mc_rldram_mrs); 959*a23fd118Syl 960*a23fd118Syl while (iteration < 2) { 961*a23fd118Syl val64 = 0x55555555aaaa0000ULL; 962*a23fd118Syl if (iteration == 1) { 963*a23fd118Syl val64 ^= 0xFFFFFFFFFFFF0000ULL; 964*a23fd118Syl } 965*a23fd118Syl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, 966*a23fd118Syl &bar0->mc_rldram_test_d0); 967*a23fd118Syl 968*a23fd118Syl val64 = 0xaaaa5a5555550000ULL; 969*a23fd118Syl if (iteration == 1) { 970*a23fd118Syl val64 ^= 0xFFFFFFFFFFFF0000ULL; 971*a23fd118Syl } 972*a23fd118Syl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, 973*a23fd118Syl &bar0->mc_rldram_test_d1); 974*a23fd118Syl 975*a23fd118Syl val64 = 0x55aaaaaaaa5a0000ULL; 976*a23fd118Syl if (iteration == 1) { 977*a23fd118Syl val64 ^= 0xFFFFFFFFFFFF0000ULL; 978*a23fd118Syl } 979*a23fd118Syl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, 980*a23fd118Syl &bar0->mc_rldram_test_d2); 981*a23fd118Syl 982*a23fd118Syl val64 = (u64) (0x0000003fffff0000ULL); 983*a23fd118Syl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, 984*a23fd118Syl &bar0->mc_rldram_test_add); 985*a23fd118Syl 986*a23fd118Syl 987*a23fd118Syl val64 = XGE_HAL_MC_RLDRAM_TEST_MODE; 988*a23fd118Syl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, 989*a23fd118Syl &bar0->mc_rldram_test_ctrl); 990*a23fd118Syl 991*a23fd118Syl val64 |= 992*a23fd118Syl XGE_HAL_MC_RLDRAM_TEST_MODE | XGE_HAL_MC_RLDRAM_TEST_WRITE | 993*a23fd118Syl XGE_HAL_MC_RLDRAM_TEST_GO; 994*a23fd118Syl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, 995*a23fd118Syl &bar0->mc_rldram_test_ctrl); 996*a23fd118Syl 997*a23fd118Syl for (cnt = 0; cnt < 5; cnt++) { 998*a23fd118Syl val64 = xge_os_pio_mem_read64(hldev->pdev, 999*a23fd118Syl hldev->regh0, &bar0->mc_rldram_test_ctrl); 1000*a23fd118Syl if (val64 & XGE_HAL_MC_RLDRAM_TEST_DONE) 1001*a23fd118Syl break; 1002*a23fd118Syl xge_os_mdelay(200); 1003*a23fd118Syl } 1004*a23fd118Syl 1005*a23fd118Syl if (cnt == 5) 1006*a23fd118Syl break; 1007*a23fd118Syl 1008*a23fd118Syl val64 = XGE_HAL_MC_RLDRAM_TEST_MODE; 1009*a23fd118Syl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, 1010*a23fd118Syl &bar0->mc_rldram_test_ctrl); 1011*a23fd118Syl 1012*a23fd118Syl val64 |= XGE_HAL_MC_RLDRAM_TEST_MODE | 1013*a23fd118Syl XGE_HAL_MC_RLDRAM_TEST_GO; 1014*a23fd118Syl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, val64, 1015*a23fd118Syl &bar0->mc_rldram_test_ctrl); 1016*a23fd118Syl 1017*a23fd118Syl for (cnt = 0; cnt < 5; cnt++) { 1018*a23fd118Syl val64 = xge_os_pio_mem_read64(hldev->pdev, 1019*a23fd118Syl hldev->regh0, &bar0->mc_rldram_test_ctrl); 1020*a23fd118Syl if (val64 & XGE_HAL_MC_RLDRAM_TEST_DONE) 1021*a23fd118Syl break; 1022*a23fd118Syl xge_os_mdelay(500); 1023*a23fd118Syl } 1024*a23fd118Syl 1025*a23fd118Syl if (cnt == 5) 1026*a23fd118Syl break; 1027*a23fd118Syl 1028*a23fd118Syl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0, 1029*a23fd118Syl &bar0->mc_rldram_test_ctrl); 1030*a23fd118Syl if (val64 & XGE_HAL_MC_RLDRAM_TEST_PASS) 1031*a23fd118Syl test_pass = 1; 1032*a23fd118Syl 1033*a23fd118Syl iteration++; 1034*a23fd118Syl } 1035*a23fd118Syl 1036*a23fd118Syl if (!test_pass) 1037*a23fd118Syl *data = 1; 1038*a23fd118Syl else 1039*a23fd118Syl *data = 0; 1040*a23fd118Syl 1041*a23fd118Syl return XGE_HAL_OK; 1042*a23fd118Syl } 1043*a23fd118Syl 1044*a23fd118Syl /* 1045*a23fd118Syl * xge_hal_eeprom_test - to verify that EEprom in the xena can be 1046*a23fd118Syl programmed. 1047*a23fd118Syl * @devh: HAL device handle. 1048*a23fd118Syl * @data:variable that returns the result of each of the test conducted by 1049*a23fd118Syl * the driver. 1050*a23fd118Syl * 1051*a23fd118Syl * Verify that EEPROM in the xena can be programmed using I2C_CONTROL 1052*a23fd118Syl * register. 1053*a23fd118Syl * Return value: 1054*a23fd118Syl * 0 on success. 1055*a23fd118Syl */ 1056*a23fd118Syl xge_hal_status_e 1057*a23fd118Syl xge_hal_eeprom_test(xge_hal_device_h devh, u64 *data) 1058*a23fd118Syl { 1059*a23fd118Syl xge_hal_device_t *hldev = (xge_hal_device_t*)devh; 1060*a23fd118Syl int fail = 0; 1061*a23fd118Syl u32 ret_data; 1062*a23fd118Syl 1063*a23fd118Syl /* Test Write Error at offset 0 */ 1064*a23fd118Syl if (!xge_hal_write_eeprom(hldev, 0, 0, 3)) 1065*a23fd118Syl fail = 1; 1066*a23fd118Syl 1067*a23fd118Syl /* Test Write at offset 4f0 */ 1068*a23fd118Syl if (xge_hal_write_eeprom(hldev, 0x4F0, 0x01234567, 3)) 1069*a23fd118Syl fail = 1; 1070*a23fd118Syl if (xge_hal_read_eeprom(hldev, 0x4F0, &ret_data)) 1071*a23fd118Syl fail = 1; 1072*a23fd118Syl 1073*a23fd118Syl if (ret_data != 0x01234567) 1074*a23fd118Syl fail = 1; 1075*a23fd118Syl 1076*a23fd118Syl /* Reset the EEPROM data go FFFF */ 1077*a23fd118Syl (void) xge_hal_write_eeprom(hldev, 0x4F0, 0xFFFFFFFF, 3); 1078*a23fd118Syl 1079*a23fd118Syl /* Test Write Request Error at offset 0x7c */ 1080*a23fd118Syl if (!xge_hal_write_eeprom(hldev, 0x07C, 0, 3)) 1081*a23fd118Syl fail = 1; 1082*a23fd118Syl 1083*a23fd118Syl /* Test Write Request at offset 0x7fc */ 1084*a23fd118Syl if (xge_hal_write_eeprom(hldev, 0x7FC, 0x01234567, 3)) 1085*a23fd118Syl fail = 1; 1086*a23fd118Syl if (xge_hal_read_eeprom(hldev, 0x7FC, &ret_data)) 1087*a23fd118Syl fail = 1; 1088*a23fd118Syl 1089*a23fd118Syl if (ret_data != 0x01234567) 1090*a23fd118Syl fail = 1; 1091*a23fd118Syl 1092*a23fd118Syl /* Reset the EEPROM data go FFFF */ 1093*a23fd118Syl (void) xge_hal_write_eeprom(hldev, 0x7FC, 0xFFFFFFFF, 3); 1094*a23fd118Syl 1095*a23fd118Syl /* Test Write Error at offset 0x80 */ 1096*a23fd118Syl if (!xge_hal_write_eeprom(hldev, 0x080, 0, 3)) 1097*a23fd118Syl fail = 1; 1098*a23fd118Syl 1099*a23fd118Syl /* Test Write Error at offset 0xfc */ 1100*a23fd118Syl if (!xge_hal_write_eeprom(hldev, 0x0FC, 0, 3)) 1101*a23fd118Syl fail = 1; 1102*a23fd118Syl 1103*a23fd118Syl /* Test Write Error at offset 0x100 */ 1104*a23fd118Syl if (!xge_hal_write_eeprom(hldev, 0x100, 0, 3)) 1105*a23fd118Syl fail = 1; 1106*a23fd118Syl 1107*a23fd118Syl /* Test Write Error at offset 4ec */ 1108*a23fd118Syl if (!xge_hal_write_eeprom(hldev, 0x4EC, 0, 3)) 1109*a23fd118Syl fail = 1; 1110*a23fd118Syl 1111*a23fd118Syl *data = fail; 1112*a23fd118Syl return XGE_HAL_OK; 1113*a23fd118Syl } 1114*a23fd118Syl 1115*a23fd118Syl /* 1116*a23fd118Syl * xge_hal_bist_test - invokes the MemBist test of the card . 1117*a23fd118Syl * @devh: HAL device handle. 1118*a23fd118Syl * xge_nic structure. 1119*a23fd118Syl * @data:variable that returns the result of each of the test conducted by 1120*a23fd118Syl * the driver. 1121*a23fd118Syl * 1122*a23fd118Syl * This invokes the MemBist test of the card. We give around 1123*a23fd118Syl * 2 secs time for the Test to complete. If it's still not complete 1124*a23fd118Syl * within this peiod, we consider that the test failed. 1125*a23fd118Syl * Return value: 1126*a23fd118Syl * 0 on success and -1 on failure. 1127*a23fd118Syl */ 1128*a23fd118Syl xge_hal_status_e 1129*a23fd118Syl xge_hal_bist_test(xge_hal_device_h devh, u64 *data) 1130*a23fd118Syl { 1131*a23fd118Syl xge_hal_device_t *hldev = (xge_hal_device_t*)devh; 1132*a23fd118Syl u8 bist = 0; 1133*a23fd118Syl int cnt = 0, ret = XGE_HAL_FAIL; 1134*a23fd118Syl 1135*a23fd118Syl xge_os_pci_read8(hldev->pdev, hldev->cfgh, 0x0f, &bist); 1136*a23fd118Syl bist |= 0x40; 1137*a23fd118Syl xge_os_pci_write8(hldev->pdev, hldev->cfgh, 0x0f, bist); 1138*a23fd118Syl 1139*a23fd118Syl while (cnt < 20) { 1140*a23fd118Syl xge_os_pci_read8(hldev->pdev, hldev->cfgh, 0x0f, &bist); 1141*a23fd118Syl if (!(bist & 0x40)) { 1142*a23fd118Syl *data = (bist & 0x0f); 1143*a23fd118Syl ret = XGE_HAL_OK; 1144*a23fd118Syl break; 1145*a23fd118Syl } 1146*a23fd118Syl xge_os_mdelay(100); 1147*a23fd118Syl cnt++; 1148*a23fd118Syl } 1149*a23fd118Syl 1150*a23fd118Syl return ret; 1151*a23fd118Syl } 1152*a23fd118Syl 1153*a23fd118Syl /* 1154*a23fd118Syl * xge_hal_link_test - verifies the link state of the nic 1155*a23fd118Syl * @devh: HAL device handle. 1156*a23fd118Syl * @data: variable that returns the result of each of the test conducted by 1157*a23fd118Syl * the driver. 1158*a23fd118Syl * 1159*a23fd118Syl * Verify the link state of the NIC and updates the input 1160*a23fd118Syl * argument 'data' appropriately. 1161*a23fd118Syl * Return value: 1162*a23fd118Syl * 0 on success. 1163*a23fd118Syl */ 1164*a23fd118Syl xge_hal_status_e 1165*a23fd118Syl xge_hal_link_test(xge_hal_device_h devh, u64 *data) 1166*a23fd118Syl { 1167*a23fd118Syl xge_hal_device_t *hldev = (xge_hal_device_t*)devh; 1168*a23fd118Syl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0; 1169*a23fd118Syl u64 val64; 1170*a23fd118Syl 1171*a23fd118Syl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0, 1172*a23fd118Syl &bar0->adapter_status); 1173*a23fd118Syl if (val64 & XGE_HAL_ADAPTER_STATUS_RMAC_LOCAL_FAULT) 1174*a23fd118Syl *data = 1; 1175*a23fd118Syl 1176*a23fd118Syl return XGE_HAL_OK; 1177*a23fd118Syl } 1178*a23fd118Syl 1179*a23fd118Syl 1180*a23fd118Syl /** 1181*a23fd118Syl * xge_hal_getpause_data -Pause frame frame generation and reception. 1182*a23fd118Syl * @devh: HAL device handle. 1183*a23fd118Syl * @tx : A field to return the pause generation capability of the NIC. 1184*a23fd118Syl * @rx : A field to return the pause reception capability of the NIC. 1185*a23fd118Syl * 1186*a23fd118Syl * Returns the Pause frame generation and reception capability of the NIC. 1187*a23fd118Syl * Return value: 1188*a23fd118Syl * void 1189*a23fd118Syl */ 1190*a23fd118Syl void xge_hal_getpause_data(xge_hal_device_h devh, int *tx, int *rx) 1191*a23fd118Syl { 1192*a23fd118Syl xge_hal_device_t *hldev = (xge_hal_device_t*)devh; 1193*a23fd118Syl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0; 1194*a23fd118Syl u64 val64; 1195*a23fd118Syl 1196*a23fd118Syl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0, 1197*a23fd118Syl &bar0->rmac_pause_cfg); 1198*a23fd118Syl if (val64 & XGE_HAL_RMAC_PAUSE_GEN_EN) 1199*a23fd118Syl *tx = 1; 1200*a23fd118Syl if (val64 & XGE_HAL_RMAC_PAUSE_RCV_EN) 1201*a23fd118Syl *rx = 1; 1202*a23fd118Syl } 1203*a23fd118Syl 1204*a23fd118Syl /** 1205*a23fd118Syl * xge_hal_setpause_data - set/reset pause frame generation. 1206*a23fd118Syl * @devh: HAL device handle. 1207*a23fd118Syl * @tx: A field that indicates the pause generation capability to be 1208*a23fd118Syl * set on the NIC. 1209*a23fd118Syl * @rx: A field that indicates the pause reception capability to be 1210*a23fd118Syl * set on the NIC. 1211*a23fd118Syl * 1212*a23fd118Syl * It can be used to set or reset Pause frame generation or reception 1213*a23fd118Syl * support of the NIC. 1214*a23fd118Syl * Return value: 1215*a23fd118Syl * int, returns 0 on Success 1216*a23fd118Syl */ 1217*a23fd118Syl 1218*a23fd118Syl int xge_hal_setpause_data(xge_hal_device_h devh, int tx, int rx) 1219*a23fd118Syl { 1220*a23fd118Syl xge_hal_device_t *hldev = (xge_hal_device_t*)devh; 1221*a23fd118Syl xge_hal_pci_bar0_t *bar0 = (xge_hal_pci_bar0_t *)hldev->bar0; 1222*a23fd118Syl u64 val64; 1223*a23fd118Syl 1224*a23fd118Syl val64 = xge_os_pio_mem_read64(hldev->pdev, hldev->regh0, 1225*a23fd118Syl &bar0->rmac_pause_cfg); 1226*a23fd118Syl if (tx) 1227*a23fd118Syl val64 |= XGE_HAL_RMAC_PAUSE_GEN_EN; 1228*a23fd118Syl else 1229*a23fd118Syl val64 &= ~XGE_HAL_RMAC_PAUSE_GEN_EN; 1230*a23fd118Syl if (rx) 1231*a23fd118Syl val64 |= XGE_HAL_RMAC_PAUSE_RCV_EN; 1232*a23fd118Syl else 1233*a23fd118Syl val64 &= ~XGE_HAL_RMAC_PAUSE_RCV_EN; 1234*a23fd118Syl xge_os_pio_mem_write64(hldev->pdev, hldev->regh0, 1235*a23fd118Syl val64, &bar0->rmac_pause_cfg); 1236*a23fd118Syl return 0; 1237*a23fd118Syl } 1238*a23fd118Syl 1239