1/****************************************************************************** 2 * This software may be used and distributed according to the terms of 3 * the GNU General Public License (GPL), incorporated herein by reference. 4 * Drivers based on or derived from this code fall under the GPL and must 5 * retain the authorship, copyright and license notice. This file is not 6 * a complete program and may only be used when the entire operating 7 * system is licensed under the GPL. 8 * See the file COPYING in this distribution for more information. 9 * 10 * vxge-config.c: Driver for Exar Corp's X3100 Series 10GbE PCIe I/O 11 * Virtualized Server Adapter. 12 * Copyright(c) 2002-2010 Exar Corp. 13 ******************************************************************************/ 14#include <linux/vmalloc.h> 15#include <linux/etherdevice.h> 16#include <linux/pci.h> 17#include <linux/pci_hotplug.h> 18#include <linux/slab.h> 19 20#include "vxge-traffic.h" 21#include "vxge-config.h" 22#include "vxge-main.h" 23 24#define VXGE_HW_VPATH_STATS_PIO_READ(offset) { \ 25 status = __vxge_hw_vpath_stats_access(vpath, \ 26 VXGE_HW_STATS_OP_READ, \ 27 offset, \ 28 &val64); \ 29 if (status != VXGE_HW_OK) \ 30 return status; \ 31} 32 33static void 34vxge_hw_vpath_set_zero_rx_frm_len(struct vxge_hw_vpath_reg __iomem *vp_reg) 35{ 36 u64 val64; 37 38 val64 = readq(&vp_reg->rxmac_vcfg0); 39 val64 &= ~VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN(0x3fff); 40 writeq(val64, &vp_reg->rxmac_vcfg0); 41 val64 = readq(&vp_reg->rxmac_vcfg0); 42} 43 44/* 45 * vxge_hw_vpath_wait_receive_idle - Wait for Rx to become idle 46 */ 47int vxge_hw_vpath_wait_receive_idle(struct __vxge_hw_device *hldev, u32 vp_id) 48{ 49 struct vxge_hw_vpath_reg __iomem *vp_reg; 50 struct __vxge_hw_virtualpath *vpath; 51 u64 val64, rxd_count, rxd_spat; 52 int count = 0, total_count = 0; 53 54 vpath = &hldev->virtual_paths[vp_id]; 55 vp_reg = vpath->vp_reg; 56 57 vxge_hw_vpath_set_zero_rx_frm_len(vp_reg); 58 59 /* Check that the ring controller for this vpath has enough free RxDs 60 * to send frames to the host. This is done by reading the 61 * PRC_RXD_DOORBELL_VPn register and comparing the read value to the 62 * RXD_SPAT value for the vpath. 63 */ 64 val64 = readq(&vp_reg->prc_cfg6); 65 rxd_spat = VXGE_HW_PRC_CFG6_GET_RXD_SPAT(val64) + 1; 66 /* Use a factor of 2 when comparing rxd_count against rxd_spat for some 67 * leg room. 68 */ 69 rxd_spat *= 2; 70 71 do { 72 mdelay(1); 73 74 rxd_count = readq(&vp_reg->prc_rxd_doorbell); 75 76 /* Check that the ring controller for this vpath does 77 * not have any frame in its pipeline. 78 */ 79 val64 = readq(&vp_reg->frm_in_progress_cnt); 80 if ((rxd_count <= rxd_spat) || (val64 > 0)) 81 count = 0; 82 else 83 count++; 84 total_count++; 85 } while ((count < VXGE_HW_MIN_SUCCESSIVE_IDLE_COUNT) && 86 (total_count < VXGE_HW_MAX_POLLING_COUNT)); 87 88 if (total_count >= VXGE_HW_MAX_POLLING_COUNT) 89 printk(KERN_ALERT "%s: Still Receiving traffic. Abort wait\n", 90 __func__); 91 92 return total_count; 93} 94 95/* vxge_hw_device_wait_receive_idle - This function waits until all frames 96 * stored in the frame buffer for each vpath assigned to the given 97 * function (hldev) have been sent to the host. 98 */ 99void vxge_hw_device_wait_receive_idle(struct __vxge_hw_device *hldev) 100{ 101 int i, total_count = 0; 102 103 for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) { 104 if (!(hldev->vpaths_deployed & vxge_mBIT(i))) 105 continue; 106 107 total_count += vxge_hw_vpath_wait_receive_idle(hldev, i); 108 if (total_count >= VXGE_HW_MAX_POLLING_COUNT) 109 break; 110 } 111} 112 113/* 114 * __vxge_hw_device_register_poll 115 * Will poll certain register for specified amount of time. 116 * Will poll until masked bit is not cleared. 117 */ 118static enum vxge_hw_status 119__vxge_hw_device_register_poll(void __iomem *reg, u64 mask, u32 max_millis) 120{ 121 u64 val64; 122 u32 i = 0; 123 enum vxge_hw_status ret = VXGE_HW_FAIL; 124 125 udelay(10); 126 127 do { 128 val64 = readq(reg); 129 if (!(val64 & mask)) 130 return VXGE_HW_OK; 131 udelay(100); 132 } while (++i <= 9); 133 134 i = 0; 135 do { 136 val64 = readq(reg); 137 if (!(val64 & mask)) 138 return VXGE_HW_OK; 139 mdelay(1); 140 } while (++i <= max_millis); 141 142 return ret; 143} 144 145static inline enum vxge_hw_status 146__vxge_hw_pio_mem_write64(u64 val64, void __iomem *addr, 147 u64 mask, u32 max_millis) 148{ 149 __vxge_hw_pio_mem_write32_lower((u32)vxge_bVALn(val64, 32, 32), addr); 150 wmb(); 151 __vxge_hw_pio_mem_write32_upper((u32)vxge_bVALn(val64, 0, 32), addr); 152 wmb(); 153 154 return __vxge_hw_device_register_poll(addr, mask, max_millis); 155} 156 157static enum vxge_hw_status 158vxge_hw_vpath_fw_api(struct __vxge_hw_virtualpath *vpath, u32 action, 159 u32 fw_memo, u32 offset, u64 *data0, u64 *data1, 160 u64 *steer_ctrl) 161{ 162 struct vxge_hw_vpath_reg __iomem *vp_reg = vpath->vp_reg; 163 enum vxge_hw_status status; 164 u64 val64; 165 u32 retry = 0, max_retry = 3; 166 167 spin_lock(&vpath->lock); 168 if (!vpath->vp_open) { 169 spin_unlock(&vpath->lock); 170 max_retry = 100; 171 } 172 173 writeq(*data0, &vp_reg->rts_access_steer_data0); 174 writeq(*data1, &vp_reg->rts_access_steer_data1); 175 wmb(); 176 177 val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(action) | 178 VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(fw_memo) | 179 VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(offset) | 180 VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE | 181 *steer_ctrl; 182 183 status = __vxge_hw_pio_mem_write64(val64, 184 &vp_reg->rts_access_steer_ctrl, 185 VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE, 186 VXGE_HW_DEF_DEVICE_POLL_MILLIS); 187 188 /* The __vxge_hw_device_register_poll can udelay for a significant 189 * amount of time, blocking other process from the CPU. If it delays 190 * for ~5secs, a NMI error can occur. A way around this is to give up 191 * the processor via msleep, but this is not allowed is under lock. 192 * So, only allow it to sleep for ~4secs if open. Otherwise, delay for 193 * 1sec and sleep for 10ms until the firmware operation has completed 194 * or timed-out. 195 */ 196 while ((status != VXGE_HW_OK) && retry++ < max_retry) { 197 if (!vpath->vp_open) 198 msleep(20); 199 status = __vxge_hw_device_register_poll( 200 &vp_reg->rts_access_steer_ctrl, 201 VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE, 202 VXGE_HW_DEF_DEVICE_POLL_MILLIS); 203 } 204 205 if (status != VXGE_HW_OK) 206 goto out; 207 208 val64 = readq(&vp_reg->rts_access_steer_ctrl); 209 if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) { 210 *data0 = readq(&vp_reg->rts_access_steer_data0); 211 *data1 = readq(&vp_reg->rts_access_steer_data1); 212 *steer_ctrl = val64; 213 } else 214 status = VXGE_HW_FAIL; 215 216out: 217 if (vpath->vp_open) 218 spin_unlock(&vpath->lock); 219 return status; 220} 221 222enum vxge_hw_status 223vxge_hw_upgrade_read_version(struct __vxge_hw_device *hldev, u32 *major, 224 u32 *minor, u32 *build) 225{ 226 u64 data0 = 0, data1 = 0, steer_ctrl = 0; 227 struct __vxge_hw_virtualpath *vpath; 228 enum vxge_hw_status status; 229 230 vpath = &hldev->virtual_paths[hldev->first_vp_id]; 231 232 status = vxge_hw_vpath_fw_api(vpath, 233 VXGE_HW_FW_UPGRADE_ACTION, 234 VXGE_HW_FW_UPGRADE_MEMO, 235 VXGE_HW_FW_UPGRADE_OFFSET_READ, 236 &data0, &data1, &steer_ctrl); 237 if (status != VXGE_HW_OK) 238 return status; 239 240 *major = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MAJOR(data0); 241 *minor = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MINOR(data0); 242 *build = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_BUILD(data0); 243 244 return status; 245} 246 247enum vxge_hw_status vxge_hw_flash_fw(struct __vxge_hw_device *hldev) 248{ 249 u64 data0 = 0, data1 = 0, steer_ctrl = 0; 250 struct __vxge_hw_virtualpath *vpath; 251 enum vxge_hw_status status; 252 u32 ret; 253 254 vpath = &hldev->virtual_paths[hldev->first_vp_id]; 255 256 status = vxge_hw_vpath_fw_api(vpath, 257 VXGE_HW_FW_UPGRADE_ACTION, 258 VXGE_HW_FW_UPGRADE_MEMO, 259 VXGE_HW_FW_UPGRADE_OFFSET_COMMIT, 260 &data0, &data1, &steer_ctrl); 261 if (status != VXGE_HW_OK) { 262 vxge_debug_init(VXGE_ERR, "%s: FW upgrade failed", __func__); 263 goto exit; 264 } 265 266 ret = VXGE_HW_RTS_ACCESS_STEER_CTRL_GET_ACTION(steer_ctrl) & 0x7F; 267 if (ret != 1) { 268 vxge_debug_init(VXGE_ERR, "%s: FW commit failed with error %d", 269 __func__, ret); 270 status = VXGE_HW_FAIL; 271 } 272 273exit: 274 return status; 275} 276 277enum vxge_hw_status 278vxge_update_fw_image(struct __vxge_hw_device *hldev, const u8 *fwdata, int size) 279{ 280 u64 data0 = 0, data1 = 0, steer_ctrl = 0; 281 struct __vxge_hw_virtualpath *vpath; 282 enum vxge_hw_status status; 283 int ret_code, sec_code; 284 285 vpath = &hldev->virtual_paths[hldev->first_vp_id]; 286 287 /* send upgrade start command */ 288 status = vxge_hw_vpath_fw_api(vpath, 289 VXGE_HW_FW_UPGRADE_ACTION, 290 VXGE_HW_FW_UPGRADE_MEMO, 291 VXGE_HW_FW_UPGRADE_OFFSET_START, 292 &data0, &data1, &steer_ctrl); 293 if (status != VXGE_HW_OK) { 294 vxge_debug_init(VXGE_ERR, " %s: Upgrade start cmd failed", 295 __func__); 296 return status; 297 } 298 299 /* Transfer fw image to adapter 16 bytes at a time */ 300 for (; size > 0; size -= VXGE_HW_FW_UPGRADE_BLK_SIZE) { 301 steer_ctrl = 0; 302 303 /* The next 128bits of fwdata to be loaded onto the adapter */ 304 data0 = *((u64 *)fwdata); 305 data1 = *((u64 *)fwdata + 1); 306 307 status = vxge_hw_vpath_fw_api(vpath, 308 VXGE_HW_FW_UPGRADE_ACTION, 309 VXGE_HW_FW_UPGRADE_MEMO, 310 VXGE_HW_FW_UPGRADE_OFFSET_SEND, 311 &data0, &data1, &steer_ctrl); 312 if (status != VXGE_HW_OK) { 313 vxge_debug_init(VXGE_ERR, "%s: Upgrade send failed", 314 __func__); 315 goto out; 316 } 317 318 ret_code = VXGE_HW_UPGRADE_GET_RET_ERR_CODE(data0); 319 switch (ret_code) { 320 case VXGE_HW_FW_UPGRADE_OK: 321 /* All OK, send next 16 bytes. */ 322 break; 323 case VXGE_FW_UPGRADE_BYTES2SKIP: 324 /* skip bytes in the stream */ 325 fwdata += (data0 >> 8) & 0xFFFFFFFF; 326 break; 327 case VXGE_HW_FW_UPGRADE_DONE: 328 goto out; 329 case VXGE_HW_FW_UPGRADE_ERR: 330 sec_code = VXGE_HW_UPGRADE_GET_SEC_ERR_CODE(data0); 331 switch (sec_code) { 332 case VXGE_HW_FW_UPGRADE_ERR_CORRUPT_DATA_1: 333 case VXGE_HW_FW_UPGRADE_ERR_CORRUPT_DATA_7: 334 printk(KERN_ERR 335 "corrupted data from .ncf file\n"); 336 break; 337 case VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_3: 338 case VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_4: 339 case VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_5: 340 case VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_6: 341 case VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_8: 342 printk(KERN_ERR "invalid .ncf file\n"); 343 break; 344 case VXGE_HW_FW_UPGRADE_ERR_BUFFER_OVERFLOW: 345 printk(KERN_ERR "buffer overflow\n"); 346 break; 347 case VXGE_HW_FW_UPGRADE_ERR_FAILED_TO_FLASH: 348 printk(KERN_ERR "failed to flash the image\n"); 349 break; 350 case VXGE_HW_FW_UPGRADE_ERR_GENERIC_ERROR_UNKNOWN: 351 printk(KERN_ERR 352 "generic error. Unknown error type\n"); 353 break; 354 default: 355 printk(KERN_ERR "Unknown error of type %d\n", 356 sec_code); 357 break; 358 } 359 status = VXGE_HW_FAIL; 360 goto out; 361 default: 362 printk(KERN_ERR "Unknown FW error: %d\n", ret_code); 363 status = VXGE_HW_FAIL; 364 goto out; 365 } 366 /* point to next 16 bytes */ 367 fwdata += VXGE_HW_FW_UPGRADE_BLK_SIZE; 368 } 369out: 370 return status; 371} 372 373enum vxge_hw_status 374vxge_hw_vpath_eprom_img_ver_get(struct __vxge_hw_device *hldev, 375 struct eprom_image *img) 376{ 377 u64 data0 = 0, data1 = 0, steer_ctrl = 0; 378 struct __vxge_hw_virtualpath *vpath; 379 enum vxge_hw_status status; 380 int i; 381 382 vpath = &hldev->virtual_paths[hldev->first_vp_id]; 383 384 for (i = 0; i < VXGE_HW_MAX_ROM_IMAGES; i++) { 385 data0 = VXGE_HW_RTS_ACCESS_STEER_ROM_IMAGE_INDEX(i); 386 data1 = steer_ctrl = 0; 387 388 status = vxge_hw_vpath_fw_api(vpath, 389 VXGE_HW_FW_API_GET_EPROM_REV, 390 VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO, 391 0, &data0, &data1, &steer_ctrl); 392 if (status != VXGE_HW_OK) 393 break; 394 395 img[i].is_valid = VXGE_HW_GET_EPROM_IMAGE_VALID(data0); 396 img[i].index = VXGE_HW_GET_EPROM_IMAGE_INDEX(data0); 397 img[i].type = VXGE_HW_GET_EPROM_IMAGE_TYPE(data0); 398 img[i].version = VXGE_HW_GET_EPROM_IMAGE_REV(data0); 399 } 400 401 return status; 402} 403 404/* 405 * __vxge_hw_channel_free - Free memory allocated for channel 406 * This function deallocates memory from the channel and various arrays 407 * in the channel 408 */ 409static void __vxge_hw_channel_free(struct __vxge_hw_channel *channel) 410{ 411 kfree(channel->work_arr); 412 kfree(channel->free_arr); 413 kfree(channel->reserve_arr); 414 kfree(channel->orig_arr); 415 kfree(channel); 416} 417 418/* 419 * __vxge_hw_channel_initialize - Initialize a channel 420 * This function initializes a channel by properly setting the 421 * various references 422 */ 423static enum vxge_hw_status 424__vxge_hw_channel_initialize(struct __vxge_hw_channel *channel) 425{ 426 u32 i; 427 struct __vxge_hw_virtualpath *vpath; 428 429 vpath = channel->vph->vpath; 430 431 if ((channel->reserve_arr != NULL) && (channel->orig_arr != NULL)) { 432 for (i = 0; i < channel->length; i++) 433 channel->orig_arr[i] = channel->reserve_arr[i]; 434 } 435 436 switch (channel->type) { 437 case VXGE_HW_CHANNEL_TYPE_FIFO: 438 vpath->fifoh = (struct __vxge_hw_fifo *)channel; 439 channel->stats = &((struct __vxge_hw_fifo *) 440 channel)->stats->common_stats; 441 break; 442 case VXGE_HW_CHANNEL_TYPE_RING: 443 vpath->ringh = (struct __vxge_hw_ring *)channel; 444 channel->stats = &((struct __vxge_hw_ring *) 445 channel)->stats->common_stats; 446 break; 447 default: 448 break; 449 } 450 451 return VXGE_HW_OK; 452} 453 454/* 455 * __vxge_hw_channel_reset - Resets a channel 456 * This function resets a channel by properly setting the various references 457 */ 458static enum vxge_hw_status 459__vxge_hw_channel_reset(struct __vxge_hw_channel *channel) 460{ 461 u32 i; 462 463 for (i = 0; i < channel->length; i++) { 464 if (channel->reserve_arr != NULL) 465 channel->reserve_arr[i] = channel->orig_arr[i]; 466 if (channel->free_arr != NULL) 467 channel->free_arr[i] = NULL; 468 if (channel->work_arr != NULL) 469 channel->work_arr[i] = NULL; 470 } 471 channel->free_ptr = channel->length; 472 channel->reserve_ptr = channel->length; 473 channel->reserve_top = 0; 474 channel->post_index = 0; 475 channel->compl_index = 0; 476 477 return VXGE_HW_OK; 478} 479 480/* 481 * __vxge_hw_device_pci_e_init 482 * Initialize certain PCI/PCI-X configuration registers 483 * with recommended values. Save config space for future hw resets. 484 */ 485static void __vxge_hw_device_pci_e_init(struct __vxge_hw_device *hldev) 486{ 487 u16 cmd = 0; 488 489 /* Set the PErr Repconse bit and SERR in PCI command register. */ 490 pci_read_config_word(hldev->pdev, PCI_COMMAND, &cmd); 491 cmd |= 0x140; 492 pci_write_config_word(hldev->pdev, PCI_COMMAND, cmd); 493 494 pci_save_state(hldev->pdev); 495} 496 497/* __vxge_hw_device_vpath_reset_in_prog_check - Check if vpath reset 498 * in progress 499 * This routine checks the vpath reset in progress register is turned zero 500 */ 501static enum vxge_hw_status 502__vxge_hw_device_vpath_reset_in_prog_check(u64 __iomem *vpath_rst_in_prog) 503{ 504 enum vxge_hw_status status; 505 status = __vxge_hw_device_register_poll(vpath_rst_in_prog, 506 VXGE_HW_VPATH_RST_IN_PROG_VPATH_RST_IN_PROG(0x1ffff), 507 VXGE_HW_DEF_DEVICE_POLL_MILLIS); 508 return status; 509} 510 511/* 512 * _hw_legacy_swapper_set - Set the swapper bits for the legacy secion. 513 * Set the swapper bits appropriately for the lagacy section. 514 */ 515static enum vxge_hw_status 516__vxge_hw_legacy_swapper_set(struct vxge_hw_legacy_reg __iomem *legacy_reg) 517{ 518 u64 val64; 519 enum vxge_hw_status status = VXGE_HW_OK; 520 521 val64 = readq(&legacy_reg->toc_swapper_fb); 522 523 wmb(); 524 525 switch (val64) { 526 case VXGE_HW_SWAPPER_INITIAL_VALUE: 527 return status; 528 529 case VXGE_HW_SWAPPER_BYTE_SWAPPED_BIT_FLIPPED: 530 writeq(VXGE_HW_SWAPPER_READ_BYTE_SWAP_ENABLE, 531 &legacy_reg->pifm_rd_swap_en); 532 writeq(VXGE_HW_SWAPPER_READ_BIT_FLAP_ENABLE, 533 &legacy_reg->pifm_rd_flip_en); 534 writeq(VXGE_HW_SWAPPER_WRITE_BYTE_SWAP_ENABLE, 535 &legacy_reg->pifm_wr_swap_en); 536 writeq(VXGE_HW_SWAPPER_WRITE_BIT_FLAP_ENABLE, 537 &legacy_reg->pifm_wr_flip_en); 538 break; 539 540 case VXGE_HW_SWAPPER_BYTE_SWAPPED: 541 writeq(VXGE_HW_SWAPPER_READ_BYTE_SWAP_ENABLE, 542 &legacy_reg->pifm_rd_swap_en); 543 writeq(VXGE_HW_SWAPPER_WRITE_BYTE_SWAP_ENABLE, 544 &legacy_reg->pifm_wr_swap_en); 545 break; 546 547 case VXGE_HW_SWAPPER_BIT_FLIPPED: 548 writeq(VXGE_HW_SWAPPER_READ_BIT_FLAP_ENABLE, 549 &legacy_reg->pifm_rd_flip_en); 550 writeq(VXGE_HW_SWAPPER_WRITE_BIT_FLAP_ENABLE, 551 &legacy_reg->pifm_wr_flip_en); 552 break; 553 } 554 555 wmb(); 556 557 val64 = readq(&legacy_reg->toc_swapper_fb); 558 559 if (val64 != VXGE_HW_SWAPPER_INITIAL_VALUE) 560 status = VXGE_HW_ERR_SWAPPER_CTRL; 561 562 return status; 563} 564 565/* 566 * __vxge_hw_device_toc_get 567 * This routine sets the swapper and reads the toc pointer and returns the 568 * memory mapped address of the toc 569 */ 570static struct vxge_hw_toc_reg __iomem * 571__vxge_hw_device_toc_get(void __iomem *bar0) 572{ 573 u64 val64; 574 struct vxge_hw_toc_reg __iomem *toc = NULL; 575 enum vxge_hw_status status; 576 577 struct vxge_hw_legacy_reg __iomem *legacy_reg = 578 (struct vxge_hw_legacy_reg __iomem *)bar0; 579 580 status = __vxge_hw_legacy_swapper_set(legacy_reg); 581 if (status != VXGE_HW_OK) 582 goto exit; 583 584 val64 = readq(&legacy_reg->toc_first_pointer); 585 toc = bar0 + val64; 586exit: 587 return toc; 588} 589 590/* 591 * __vxge_hw_device_reg_addr_get 592 * This routine sets the swapper and reads the toc pointer and initializes the 593 * register location pointers in the device object. It waits until the ric is 594 * completed initializing registers. 595 */ 596static enum vxge_hw_status 597__vxge_hw_device_reg_addr_get(struct __vxge_hw_device *hldev) 598{ 599 u64 val64; 600 u32 i; 601 enum vxge_hw_status status = VXGE_HW_OK; 602 603 hldev->legacy_reg = hldev->bar0; 604 605 hldev->toc_reg = __vxge_hw_device_toc_get(hldev->bar0); 606 if (hldev->toc_reg == NULL) { 607 status = VXGE_HW_FAIL; 608 goto exit; 609 } 610 611 val64 = readq(&hldev->toc_reg->toc_common_pointer); 612 hldev->common_reg = hldev->bar0 + val64; 613 614 val64 = readq(&hldev->toc_reg->toc_mrpcim_pointer); 615 hldev->mrpcim_reg = hldev->bar0 + val64; 616 617 for (i = 0; i < VXGE_HW_TITAN_SRPCIM_REG_SPACES; i++) { 618 val64 = readq(&hldev->toc_reg->toc_srpcim_pointer[i]); 619 hldev->srpcim_reg[i] = hldev->bar0 + val64; 620 } 621 622 for (i = 0; i < VXGE_HW_TITAN_VPMGMT_REG_SPACES; i++) { 623 val64 = readq(&hldev->toc_reg->toc_vpmgmt_pointer[i]); 624 hldev->vpmgmt_reg[i] = hldev->bar0 + val64; 625 } 626 627 for (i = 0; i < VXGE_HW_TITAN_VPATH_REG_SPACES; i++) { 628 val64 = readq(&hldev->toc_reg->toc_vpath_pointer[i]); 629 hldev->vpath_reg[i] = hldev->bar0 + val64; 630 } 631 632 val64 = readq(&hldev->toc_reg->toc_kdfc); 633 634 switch (VXGE_HW_TOC_GET_KDFC_INITIAL_BIR(val64)) { 635 case 0: 636 hldev->kdfc = hldev->bar0 + VXGE_HW_TOC_GET_KDFC_INITIAL_OFFSET(val64) ; 637 break; 638 default: 639 break; 640 } 641 642 status = __vxge_hw_device_vpath_reset_in_prog_check( 643 (u64 __iomem *)&hldev->common_reg->vpath_rst_in_prog); 644exit: 645 return status; 646} 647 648/* 649 * __vxge_hw_device_access_rights_get: Get Access Rights of the driver 650 * This routine returns the Access Rights of the driver 651 */ 652static u32 653__vxge_hw_device_access_rights_get(u32 host_type, u32 func_id) 654{ 655 u32 access_rights = VXGE_HW_DEVICE_ACCESS_RIGHT_VPATH; 656 657 switch (host_type) { 658 case VXGE_HW_NO_MR_NO_SR_NORMAL_FUNCTION: 659 if (func_id == 0) { 660 access_rights |= VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM | 661 VXGE_HW_DEVICE_ACCESS_RIGHT_SRPCIM; 662 } 663 break; 664 case VXGE_HW_MR_NO_SR_VH0_BASE_FUNCTION: 665 access_rights |= VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM | 666 VXGE_HW_DEVICE_ACCESS_RIGHT_SRPCIM; 667 break; 668 case VXGE_HW_NO_MR_SR_VH0_FUNCTION0: 669 access_rights |= VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM | 670 VXGE_HW_DEVICE_ACCESS_RIGHT_SRPCIM; 671 break; 672 case VXGE_HW_NO_MR_SR_VH0_VIRTUAL_FUNCTION: 673 case VXGE_HW_SR_VH_VIRTUAL_FUNCTION: 674 case VXGE_HW_MR_SR_VH0_INVALID_CONFIG: 675 break; 676 case VXGE_HW_SR_VH_FUNCTION0: 677 case VXGE_HW_VH_NORMAL_FUNCTION: 678 access_rights |= VXGE_HW_DEVICE_ACCESS_RIGHT_SRPCIM; 679 break; 680 } 681 682 return access_rights; 683} 684/* 685 * __vxge_hw_device_is_privilaged 686 * This routine checks if the device function is privilaged or not 687 */ 688 689enum vxge_hw_status 690__vxge_hw_device_is_privilaged(u32 host_type, u32 func_id) 691{ 692 if (__vxge_hw_device_access_rights_get(host_type, 693 func_id) & 694 VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM) 695 return VXGE_HW_OK; 696 else 697 return VXGE_HW_ERR_PRIVILAGED_OPEARATION; 698} 699 700/* 701 * __vxge_hw_vpath_func_id_get - Get the function id of the vpath. 702 * Returns the function number of the vpath. 703 */ 704static u32 705__vxge_hw_vpath_func_id_get(struct vxge_hw_vpmgmt_reg __iomem *vpmgmt_reg) 706{ 707 u64 val64; 708 709 val64 = readq(&vpmgmt_reg->vpath_to_func_map_cfg1); 710 711 return 712 (u32)VXGE_HW_VPATH_TO_FUNC_MAP_CFG1_GET_VPATH_TO_FUNC_MAP_CFG1(val64); 713} 714 715/* 716 * __vxge_hw_device_host_info_get 717 * This routine returns the host type assignments 718 */ 719static void __vxge_hw_device_host_info_get(struct __vxge_hw_device *hldev) 720{ 721 u64 val64; 722 u32 i; 723 724 val64 = readq(&hldev->common_reg->host_type_assignments); 725 726 hldev->host_type = 727 (u32)VXGE_HW_HOST_TYPE_ASSIGNMENTS_GET_HOST_TYPE_ASSIGNMENTS(val64); 728 729 hldev->vpath_assignments = readq(&hldev->common_reg->vpath_assignments); 730 731 for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) { 732 if (!(hldev->vpath_assignments & vxge_mBIT(i))) 733 continue; 734 735 hldev->func_id = 736 __vxge_hw_vpath_func_id_get(hldev->vpmgmt_reg[i]); 737 738 hldev->access_rights = __vxge_hw_device_access_rights_get( 739 hldev->host_type, hldev->func_id); 740 741 hldev->virtual_paths[i].vp_open = VXGE_HW_VP_NOT_OPEN; 742 hldev->virtual_paths[i].vp_reg = hldev->vpath_reg[i]; 743 744 hldev->first_vp_id = i; 745 break; 746 } 747} 748 749/* 750 * __vxge_hw_verify_pci_e_info - Validate the pci-e link parameters such as 751 * link width and signalling rate. 752 */ 753static enum vxge_hw_status 754__vxge_hw_verify_pci_e_info(struct __vxge_hw_device *hldev) 755{ 756 struct pci_dev *dev = hldev->pdev; 757 u16 lnk; 758 759 /* Get the negotiated link width and speed from PCI config space */ 760 pci_read_config_word(dev, dev->pcie_cap + PCI_EXP_LNKSTA, &lnk); 761 762 if ((lnk & PCI_EXP_LNKSTA_CLS) != 1) 763 return VXGE_HW_ERR_INVALID_PCI_INFO; 764 765 switch ((lnk & PCI_EXP_LNKSTA_NLW) >> 4) { 766 case PCIE_LNK_WIDTH_RESRV: 767 case PCIE_LNK_X1: 768 case PCIE_LNK_X2: 769 case PCIE_LNK_X4: 770 case PCIE_LNK_X8: 771 break; 772 default: 773 return VXGE_HW_ERR_INVALID_PCI_INFO; 774 } 775 776 return VXGE_HW_OK; 777} 778 779/* 780 * __vxge_hw_device_initialize 781 * Initialize Titan-V hardware. 782 */ 783static enum vxge_hw_status 784__vxge_hw_device_initialize(struct __vxge_hw_device *hldev) 785{ 786 enum vxge_hw_status status = VXGE_HW_OK; 787 788 if (VXGE_HW_OK == __vxge_hw_device_is_privilaged(hldev->host_type, 789 hldev->func_id)) { 790 /* Validate the pci-e link width and speed */ 791 status = __vxge_hw_verify_pci_e_info(hldev); 792 if (status != VXGE_HW_OK) 793 goto exit; 794 } 795 796exit: 797 return status; 798} 799 800/* 801 * __vxge_hw_vpath_fw_ver_get - Get the fw version 802 * Returns FW Version 803 */ 804static enum vxge_hw_status 805__vxge_hw_vpath_fw_ver_get(struct __vxge_hw_virtualpath *vpath, 806 struct vxge_hw_device_hw_info *hw_info) 807{ 808 struct vxge_hw_device_version *fw_version = &hw_info->fw_version; 809 struct vxge_hw_device_date *fw_date = &hw_info->fw_date; 810 struct vxge_hw_device_version *flash_version = &hw_info->flash_version; 811 struct vxge_hw_device_date *flash_date = &hw_info->flash_date; 812 u64 data0, data1 = 0, steer_ctrl = 0; 813 enum vxge_hw_status status; 814 815 status = vxge_hw_vpath_fw_api(vpath, 816 VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_ENTRY, 817 VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO, 818 0, &data0, &data1, &steer_ctrl); 819 if (status != VXGE_HW_OK) 820 goto exit; 821 822 fw_date->day = 823 (u32) VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_DAY(data0); 824 fw_date->month = 825 (u32) VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MONTH(data0); 826 fw_date->year = 827 (u32) VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_YEAR(data0); 828 829 snprintf(fw_date->date, VXGE_HW_FW_STRLEN, "%2.2d/%2.2d/%4.4d", 830 fw_date->month, fw_date->day, fw_date->year); 831 832 fw_version->major = 833 (u32) VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MAJOR(data0); 834 fw_version->minor = 835 (u32) VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MINOR(data0); 836 fw_version->build = 837 (u32) VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_BUILD(data0); 838 839 snprintf(fw_version->version, VXGE_HW_FW_STRLEN, "%d.%d.%d", 840 fw_version->major, fw_version->minor, fw_version->build); 841 842 flash_date->day = 843 (u32) VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_DAY(data1); 844 flash_date->month = 845 (u32) VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MONTH(data1); 846 flash_date->year = 847 (u32) VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_YEAR(data1); 848 849 snprintf(flash_date->date, VXGE_HW_FW_STRLEN, "%2.2d/%2.2d/%4.4d", 850 flash_date->month, flash_date->day, flash_date->year); 851 852 flash_version->major = 853 (u32) VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MAJOR(data1); 854 flash_version->minor = 855 (u32) VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MINOR(data1); 856 flash_version->build = 857 (u32) VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_BUILD(data1); 858 859 snprintf(flash_version->version, VXGE_HW_FW_STRLEN, "%d.%d.%d", 860 flash_version->major, flash_version->minor, 861 flash_version->build); 862 863exit: 864 return status; 865} 866 867/* 868 * __vxge_hw_vpath_card_info_get - Get the serial numbers, 869 * part number and product description. 870 */ 871static enum vxge_hw_status 872__vxge_hw_vpath_card_info_get(struct __vxge_hw_virtualpath *vpath, 873 struct vxge_hw_device_hw_info *hw_info) 874{ 875 enum vxge_hw_status status; 876 u64 data0, data1 = 0, steer_ctrl = 0; 877 u8 *serial_number = hw_info->serial_number; 878 u8 *part_number = hw_info->part_number; 879 u8 *product_desc = hw_info->product_desc; 880 u32 i, j = 0; 881 882 data0 = VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_SERIAL_NUMBER; 883 884 status = vxge_hw_vpath_fw_api(vpath, 885 VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY, 886 VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO, 887 0, &data0, &data1, &steer_ctrl); 888 if (status != VXGE_HW_OK) 889 return status; 890 891 ((u64 *)serial_number)[0] = be64_to_cpu(data0); 892 ((u64 *)serial_number)[1] = be64_to_cpu(data1); 893 894 data0 = VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_PART_NUMBER; 895 data1 = steer_ctrl = 0; 896 897 status = vxge_hw_vpath_fw_api(vpath, 898 VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY, 899 VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO, 900 0, &data0, &data1, &steer_ctrl); 901 if (status != VXGE_HW_OK) 902 return status; 903 904 ((u64 *)part_number)[0] = be64_to_cpu(data0); 905 ((u64 *)part_number)[1] = be64_to_cpu(data1); 906 907 for (i = VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_DESC_0; 908 i <= VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_DESC_3; i++) { 909 data0 = i; 910 data1 = steer_ctrl = 0; 911 912 status = vxge_hw_vpath_fw_api(vpath, 913 VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY, 914 VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO, 915 0, &data0, &data1, &steer_ctrl); 916 if (status != VXGE_HW_OK) 917 return status; 918 919 ((u64 *)product_desc)[j++] = be64_to_cpu(data0); 920 ((u64 *)product_desc)[j++] = be64_to_cpu(data1); 921 } 922 923 return status; 924} 925 926/* 927 * __vxge_hw_vpath_pci_func_mode_get - Get the pci mode 928 * Returns pci function mode 929 */ 930static enum vxge_hw_status 931__vxge_hw_vpath_pci_func_mode_get(struct __vxge_hw_virtualpath *vpath, 932 struct vxge_hw_device_hw_info *hw_info) 933{ 934 u64 data0, data1 = 0, steer_ctrl = 0; 935 enum vxge_hw_status status; 936 937 data0 = 0; 938 939 status = vxge_hw_vpath_fw_api(vpath, 940 VXGE_HW_FW_API_GET_FUNC_MODE, 941 VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO, 942 0, &data0, &data1, &steer_ctrl); 943 if (status != VXGE_HW_OK) 944 return status; 945 946 hw_info->function_mode = VXGE_HW_GET_FUNC_MODE_VAL(data0); 947 return status; 948} 949 950/* 951 * __vxge_hw_vpath_addr_get - Get the hw address entry for this vpath 952 * from MAC address table. 953 */ 954static enum vxge_hw_status 955__vxge_hw_vpath_addr_get(struct __vxge_hw_virtualpath *vpath, 956 u8 *macaddr, u8 *macaddr_mask) 957{ 958 u64 action = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LIST_FIRST_ENTRY, 959 data0 = 0, data1 = 0, steer_ctrl = 0; 960 enum vxge_hw_status status; 961 int i; 962 963 do { 964 status = vxge_hw_vpath_fw_api(vpath, action, 965 VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA, 966 0, &data0, &data1, &steer_ctrl); 967 if (status != VXGE_HW_OK) 968 goto exit; 969 970 data0 = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_DA_MAC_ADDR(data0); 971 data1 = VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_DA_MAC_ADDR_MASK( 972 data1); 973 974 for (i = ETH_ALEN; i > 0; i--) { 975 macaddr[i - 1] = (u8) (data0 & 0xFF); 976 data0 >>= 8; 977 978 macaddr_mask[i - 1] = (u8) (data1 & 0xFF); 979 data1 >>= 8; 980 } 981 982 action = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LIST_NEXT_ENTRY; 983 data0 = 0, data1 = 0, steer_ctrl = 0; 984 985 } while (!is_valid_ether_addr(macaddr)); 986exit: 987 return status; 988} 989 990/** 991 * vxge_hw_device_hw_info_get - Get the hw information 992 * Returns the vpath mask that has the bits set for each vpath allocated 993 * for the driver, FW version information, and the first mac address for 994 * each vpath 995 */ 996enum vxge_hw_status __devinit 997vxge_hw_device_hw_info_get(void __iomem *bar0, 998 struct vxge_hw_device_hw_info *hw_info) 999{ 1000 u32 i; 1001 u64 val64; 1002 struct vxge_hw_toc_reg __iomem *toc; 1003 struct vxge_hw_mrpcim_reg __iomem *mrpcim_reg; 1004 struct vxge_hw_common_reg __iomem *common_reg; 1005 struct vxge_hw_vpmgmt_reg __iomem *vpmgmt_reg; 1006 enum vxge_hw_status status; 1007 struct __vxge_hw_virtualpath vpath; 1008 1009 memset(hw_info, 0, sizeof(struct vxge_hw_device_hw_info)); 1010 1011 toc = __vxge_hw_device_toc_get(bar0); 1012 if (toc == NULL) { 1013 status = VXGE_HW_ERR_CRITICAL; 1014 goto exit; 1015 } 1016 1017 val64 = readq(&toc->toc_common_pointer); 1018 common_reg = bar0 + val64; 1019 1020 status = __vxge_hw_device_vpath_reset_in_prog_check( 1021 (u64 __iomem *)&common_reg->vpath_rst_in_prog); 1022 if (status != VXGE_HW_OK) 1023 goto exit; 1024 1025 hw_info->vpath_mask = readq(&common_reg->vpath_assignments); 1026 1027 val64 = readq(&common_reg->host_type_assignments); 1028 1029 hw_info->host_type = 1030 (u32)VXGE_HW_HOST_TYPE_ASSIGNMENTS_GET_HOST_TYPE_ASSIGNMENTS(val64); 1031 1032 for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) { 1033 if (!((hw_info->vpath_mask) & vxge_mBIT(i))) 1034 continue; 1035 1036 val64 = readq(&toc->toc_vpmgmt_pointer[i]); 1037 1038 vpmgmt_reg = bar0 + val64; 1039 1040 hw_info->func_id = __vxge_hw_vpath_func_id_get(vpmgmt_reg); 1041 if (__vxge_hw_device_access_rights_get(hw_info->host_type, 1042 hw_info->func_id) & 1043 VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM) { 1044 1045 val64 = readq(&toc->toc_mrpcim_pointer); 1046 1047 mrpcim_reg = bar0 + val64; 1048 1049 writeq(0, &mrpcim_reg->xgmac_gen_fw_memo_mask); 1050 wmb(); 1051 } 1052 1053 val64 = readq(&toc->toc_vpath_pointer[i]); 1054 1055 spin_lock_init(&vpath.lock); 1056 vpath.vp_reg = bar0 + val64; 1057 vpath.vp_open = VXGE_HW_VP_NOT_OPEN; 1058 1059 status = __vxge_hw_vpath_pci_func_mode_get(&vpath, hw_info); 1060 if (status != VXGE_HW_OK) 1061 goto exit; 1062 1063 status = __vxge_hw_vpath_fw_ver_get(&vpath, hw_info); 1064 if (status != VXGE_HW_OK) 1065 goto exit; 1066 1067 status = __vxge_hw_vpath_card_info_get(&vpath, hw_info); 1068 if (status != VXGE_HW_OK) 1069 goto exit; 1070 1071 break; 1072 } 1073 1074 for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) { 1075 if (!((hw_info->vpath_mask) & vxge_mBIT(i))) 1076 continue; 1077 1078 val64 = readq(&toc->toc_vpath_pointer[i]); 1079 vpath.vp_reg = bar0 + val64; 1080 vpath.vp_open = VXGE_HW_VP_NOT_OPEN; 1081 1082 status = __vxge_hw_vpath_addr_get(&vpath, 1083 hw_info->mac_addrs[i], 1084 hw_info->mac_addr_masks[i]); 1085 if (status != VXGE_HW_OK) 1086 goto exit; 1087 } 1088exit: 1089 return status; 1090} 1091 1092/* 1093 * __vxge_hw_blockpool_destroy - Deallocates the block pool 1094 */ 1095static void __vxge_hw_blockpool_destroy(struct __vxge_hw_blockpool *blockpool) 1096{ 1097 struct __vxge_hw_device *hldev; 1098 struct list_head *p, *n; 1099 u16 ret; 1100 1101 if (blockpool == NULL) { 1102 ret = 1; 1103 goto exit; 1104 } 1105 1106 hldev = blockpool->hldev; 1107 1108 list_for_each_safe(p, n, &blockpool->free_block_list) { 1109 pci_unmap_single(hldev->pdev, 1110 ((struct __vxge_hw_blockpool_entry *)p)->dma_addr, 1111 ((struct __vxge_hw_blockpool_entry *)p)->length, 1112 PCI_DMA_BIDIRECTIONAL); 1113 1114 vxge_os_dma_free(hldev->pdev, 1115 ((struct __vxge_hw_blockpool_entry *)p)->memblock, 1116 &((struct __vxge_hw_blockpool_entry *)p)->acc_handle); 1117 1118 list_del(&((struct __vxge_hw_blockpool_entry *)p)->item); 1119 kfree(p); 1120 blockpool->pool_size--; 1121 } 1122 1123 list_for_each_safe(p, n, &blockpool->free_entry_list) { 1124 list_del(&((struct __vxge_hw_blockpool_entry *)p)->item); 1125 kfree((void *)p); 1126 } 1127 ret = 0; 1128exit: 1129 return; 1130} 1131 1132/* 1133 * __vxge_hw_blockpool_create - Create block pool 1134 */ 1135static enum vxge_hw_status 1136__vxge_hw_blockpool_create(struct __vxge_hw_device *hldev, 1137 struct __vxge_hw_blockpool *blockpool, 1138 u32 pool_size, 1139 u32 pool_max) 1140{ 1141 u32 i; 1142 struct __vxge_hw_blockpool_entry *entry = NULL; 1143 void *memblock; 1144 dma_addr_t dma_addr; 1145 struct pci_dev *dma_handle; 1146 struct pci_dev *acc_handle; 1147 enum vxge_hw_status status = VXGE_HW_OK; 1148 1149 if (blockpool == NULL) { 1150 status = VXGE_HW_FAIL; 1151 goto blockpool_create_exit; 1152 } 1153 1154 blockpool->hldev = hldev; 1155 blockpool->block_size = VXGE_HW_BLOCK_SIZE; 1156 blockpool->pool_size = 0; 1157 blockpool->pool_max = pool_max; 1158 blockpool->req_out = 0; 1159 1160 INIT_LIST_HEAD(&blockpool->free_block_list); 1161 INIT_LIST_HEAD(&blockpool->free_entry_list); 1162 1163 for (i = 0; i < pool_size + pool_max; i++) { 1164 entry = kzalloc(sizeof(struct __vxge_hw_blockpool_entry), 1165 GFP_KERNEL); 1166 if (entry == NULL) { 1167 __vxge_hw_blockpool_destroy(blockpool); 1168 status = VXGE_HW_ERR_OUT_OF_MEMORY; 1169 goto blockpool_create_exit; 1170 } 1171 list_add(&entry->item, &blockpool->free_entry_list); 1172 } 1173 1174 for (i = 0; i < pool_size; i++) { 1175 memblock = vxge_os_dma_malloc( 1176 hldev->pdev, 1177 VXGE_HW_BLOCK_SIZE, 1178 &dma_handle, 1179 &acc_handle); 1180 if (memblock == NULL) { 1181 __vxge_hw_blockpool_destroy(blockpool); 1182 status = VXGE_HW_ERR_OUT_OF_MEMORY; 1183 goto blockpool_create_exit; 1184 } 1185 1186 dma_addr = pci_map_single(hldev->pdev, memblock, 1187 VXGE_HW_BLOCK_SIZE, PCI_DMA_BIDIRECTIONAL); 1188 if (unlikely(pci_dma_mapping_error(hldev->pdev, 1189 dma_addr))) { 1190 vxge_os_dma_free(hldev->pdev, memblock, &acc_handle); 1191 __vxge_hw_blockpool_destroy(blockpool); 1192 status = VXGE_HW_ERR_OUT_OF_MEMORY; 1193 goto blockpool_create_exit; 1194 } 1195 1196 if (!list_empty(&blockpool->free_entry_list)) 1197 entry = (struct __vxge_hw_blockpool_entry *) 1198 list_first_entry(&blockpool->free_entry_list, 1199 struct __vxge_hw_blockpool_entry, 1200 item); 1201 1202 if (entry == NULL) 1203 entry = 1204 kzalloc(sizeof(struct __vxge_hw_blockpool_entry), 1205 GFP_KERNEL); 1206 if (entry != NULL) { 1207 list_del(&entry->item); 1208 entry->length = VXGE_HW_BLOCK_SIZE; 1209 entry->memblock = memblock; 1210 entry->dma_addr = dma_addr; 1211 entry->acc_handle = acc_handle; 1212 entry->dma_handle = dma_handle; 1213 list_add(&entry->item, 1214 &blockpool->free_block_list); 1215 blockpool->pool_size++; 1216 } else { 1217 __vxge_hw_blockpool_destroy(blockpool); 1218 status = VXGE_HW_ERR_OUT_OF_MEMORY; 1219 goto blockpool_create_exit; 1220 } 1221 } 1222 1223blockpool_create_exit: 1224 return status; 1225} 1226 1227/* 1228 * __vxge_hw_device_fifo_config_check - Check fifo configuration. 1229 * Check the fifo configuration 1230 */ 1231static enum vxge_hw_status 1232__vxge_hw_device_fifo_config_check(struct vxge_hw_fifo_config *fifo_config) 1233{ 1234 if ((fifo_config->fifo_blocks < VXGE_HW_MIN_FIFO_BLOCKS) || 1235 (fifo_config->fifo_blocks > VXGE_HW_MAX_FIFO_BLOCKS)) 1236 return VXGE_HW_BADCFG_FIFO_BLOCKS; 1237 1238 return VXGE_HW_OK; 1239} 1240 1241/* 1242 * __vxge_hw_device_vpath_config_check - Check vpath configuration. 1243 * Check the vpath configuration 1244 */ 1245static enum vxge_hw_status 1246__vxge_hw_device_vpath_config_check(struct vxge_hw_vp_config *vp_config) 1247{ 1248 enum vxge_hw_status status; 1249 1250 if ((vp_config->min_bandwidth < VXGE_HW_VPATH_BANDWIDTH_MIN) || 1251 (vp_config->min_bandwidth > VXGE_HW_VPATH_BANDWIDTH_MAX)) 1252 return VXGE_HW_BADCFG_VPATH_MIN_BANDWIDTH; 1253 1254 status = __vxge_hw_device_fifo_config_check(&vp_config->fifo); 1255 if (status != VXGE_HW_OK) 1256 return status; 1257 1258 if ((vp_config->mtu != VXGE_HW_VPATH_USE_FLASH_DEFAULT_INITIAL_MTU) && 1259 ((vp_config->mtu < VXGE_HW_VPATH_MIN_INITIAL_MTU) || 1260 (vp_config->mtu > VXGE_HW_VPATH_MAX_INITIAL_MTU))) 1261 return VXGE_HW_BADCFG_VPATH_MTU; 1262 1263 if ((vp_config->rpa_strip_vlan_tag != 1264 VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_USE_FLASH_DEFAULT) && 1265 (vp_config->rpa_strip_vlan_tag != 1266 VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_ENABLE) && 1267 (vp_config->rpa_strip_vlan_tag != 1268 VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_DISABLE)) 1269 return VXGE_HW_BADCFG_VPATH_RPA_STRIP_VLAN_TAG; 1270 1271 return VXGE_HW_OK; 1272} 1273 1274/* 1275 * __vxge_hw_device_config_check - Check device configuration. 1276 * Check the device configuration 1277 */ 1278static enum vxge_hw_status 1279__vxge_hw_device_config_check(struct vxge_hw_device_config *new_config) 1280{ 1281 u32 i; 1282 enum vxge_hw_status status; 1283 1284 if ((new_config->intr_mode != VXGE_HW_INTR_MODE_IRQLINE) && 1285 (new_config->intr_mode != VXGE_HW_INTR_MODE_MSIX) && 1286 (new_config->intr_mode != VXGE_HW_INTR_MODE_MSIX_ONE_SHOT) && 1287 (new_config->intr_mode != VXGE_HW_INTR_MODE_DEF)) 1288 return VXGE_HW_BADCFG_INTR_MODE; 1289 1290 if ((new_config->rts_mac_en != VXGE_HW_RTS_MAC_DISABLE) && 1291 (new_config->rts_mac_en != VXGE_HW_RTS_MAC_ENABLE)) 1292 return VXGE_HW_BADCFG_RTS_MAC_EN; 1293 1294 for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) { 1295 status = __vxge_hw_device_vpath_config_check( 1296 &new_config->vp_config[i]); 1297 if (status != VXGE_HW_OK) 1298 return status; 1299 } 1300 1301 return VXGE_HW_OK; 1302} 1303 1304/* 1305 * vxge_hw_device_initialize - Initialize Titan device. 1306 * Initialize Titan device. Note that all the arguments of this public API 1307 * are 'IN', including @hldev. Driver cooperates with 1308 * OS to find new Titan device, locate its PCI and memory spaces. 1309 * 1310 * When done, the driver allocates sizeof(struct __vxge_hw_device) bytes for HW 1311 * to enable the latter to perform Titan hardware initialization. 1312 */ 1313enum vxge_hw_status __devinit 1314vxge_hw_device_initialize( 1315 struct __vxge_hw_device **devh, 1316 struct vxge_hw_device_attr *attr, 1317 struct vxge_hw_device_config *device_config) 1318{ 1319 u32 i; 1320 u32 nblocks = 0; 1321 struct __vxge_hw_device *hldev = NULL; 1322 enum vxge_hw_status status = VXGE_HW_OK; 1323 1324 status = __vxge_hw_device_config_check(device_config); 1325 if (status != VXGE_HW_OK) 1326 goto exit; 1327 1328 hldev = vzalloc(sizeof(struct __vxge_hw_device)); 1329 if (hldev == NULL) { 1330 status = VXGE_HW_ERR_OUT_OF_MEMORY; 1331 goto exit; 1332 } 1333 1334 hldev->magic = VXGE_HW_DEVICE_MAGIC; 1335 1336 vxge_hw_device_debug_set(hldev, VXGE_ERR, VXGE_COMPONENT_ALL); 1337 1338 /* apply config */ 1339 memcpy(&hldev->config, device_config, 1340 sizeof(struct vxge_hw_device_config)); 1341 1342 hldev->bar0 = attr->bar0; 1343 hldev->pdev = attr->pdev; 1344 1345 hldev->uld_callbacks = attr->uld_callbacks; 1346 1347 __vxge_hw_device_pci_e_init(hldev); 1348 1349 status = __vxge_hw_device_reg_addr_get(hldev); 1350 if (status != VXGE_HW_OK) { 1351 vfree(hldev); 1352 goto exit; 1353 } 1354 1355 __vxge_hw_device_host_info_get(hldev); 1356 1357 /* Incrementing for stats blocks */ 1358 nblocks++; 1359 1360 for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) { 1361 if (!(hldev->vpath_assignments & vxge_mBIT(i))) 1362 continue; 1363 1364 if (device_config->vp_config[i].ring.enable == 1365 VXGE_HW_RING_ENABLE) 1366 nblocks += device_config->vp_config[i].ring.ring_blocks; 1367 1368 if (device_config->vp_config[i].fifo.enable == 1369 VXGE_HW_FIFO_ENABLE) 1370 nblocks += device_config->vp_config[i].fifo.fifo_blocks; 1371 nblocks++; 1372 } 1373 1374 if (__vxge_hw_blockpool_create(hldev, 1375 &hldev->block_pool, 1376 device_config->dma_blockpool_initial + nblocks, 1377 device_config->dma_blockpool_max + nblocks) != VXGE_HW_OK) { 1378 1379 vxge_hw_device_terminate(hldev); 1380 status = VXGE_HW_ERR_OUT_OF_MEMORY; 1381 goto exit; 1382 } 1383 1384 status = __vxge_hw_device_initialize(hldev); 1385 if (status != VXGE_HW_OK) { 1386 vxge_hw_device_terminate(hldev); 1387 goto exit; 1388 } 1389 1390 *devh = hldev; 1391exit: 1392 return status; 1393} 1394 1395/* 1396 * vxge_hw_device_terminate - Terminate Titan device. 1397 * Terminate HW device. 1398 */ 1399void 1400vxge_hw_device_terminate(struct __vxge_hw_device *hldev) 1401{ 1402 vxge_assert(hldev->magic == VXGE_HW_DEVICE_MAGIC); 1403 1404 hldev->magic = VXGE_HW_DEVICE_DEAD; 1405 __vxge_hw_blockpool_destroy(&hldev->block_pool); 1406 vfree(hldev); 1407} 1408 1409/* 1410 * __vxge_hw_vpath_stats_access - Get the statistics from the given location 1411 * and offset and perform an operation 1412 */ 1413static enum vxge_hw_status 1414__vxge_hw_vpath_stats_access(struct __vxge_hw_virtualpath *vpath, 1415 u32 operation, u32 offset, u64 *stat) 1416{ 1417 u64 val64; 1418 enum vxge_hw_status status = VXGE_HW_OK; 1419 struct vxge_hw_vpath_reg __iomem *vp_reg; 1420 1421 if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) { 1422 status = VXGE_HW_ERR_VPATH_NOT_OPEN; 1423 goto vpath_stats_access_exit; 1424 } 1425 1426 vp_reg = vpath->vp_reg; 1427 1428 val64 = VXGE_HW_XMAC_STATS_ACCESS_CMD_OP(operation) | 1429 VXGE_HW_XMAC_STATS_ACCESS_CMD_STROBE | 1430 VXGE_HW_XMAC_STATS_ACCESS_CMD_OFFSET_SEL(offset); 1431 1432 status = __vxge_hw_pio_mem_write64(val64, 1433 &vp_reg->xmac_stats_access_cmd, 1434 VXGE_HW_XMAC_STATS_ACCESS_CMD_STROBE, 1435 vpath->hldev->config.device_poll_millis); 1436 if ((status == VXGE_HW_OK) && (operation == VXGE_HW_STATS_OP_READ)) 1437 *stat = readq(&vp_reg->xmac_stats_access_data); 1438 else 1439 *stat = 0; 1440 1441vpath_stats_access_exit: 1442 return status; 1443} 1444 1445/* 1446 * __vxge_hw_vpath_xmac_tx_stats_get - Get the TX Statistics of a vpath 1447 */ 1448static enum vxge_hw_status 1449__vxge_hw_vpath_xmac_tx_stats_get(struct __vxge_hw_virtualpath *vpath, 1450 struct vxge_hw_xmac_vpath_tx_stats *vpath_tx_stats) 1451{ 1452 u64 *val64; 1453 int i; 1454 u32 offset = VXGE_HW_STATS_VPATH_TX_OFFSET; 1455 enum vxge_hw_status status = VXGE_HW_OK; 1456 1457 val64 = (u64 *)vpath_tx_stats; 1458 1459 if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) { 1460 status = VXGE_HW_ERR_VPATH_NOT_OPEN; 1461 goto exit; 1462 } 1463 1464 for (i = 0; i < sizeof(struct vxge_hw_xmac_vpath_tx_stats) / 8; i++) { 1465 status = __vxge_hw_vpath_stats_access(vpath, 1466 VXGE_HW_STATS_OP_READ, 1467 offset, val64); 1468 if (status != VXGE_HW_OK) 1469 goto exit; 1470 offset++; 1471 val64++; 1472 } 1473exit: 1474 return status; 1475} 1476 1477/* 1478 * __vxge_hw_vpath_xmac_rx_stats_get - Get the RX Statistics of a vpath 1479 */ 1480static enum vxge_hw_status 1481__vxge_hw_vpath_xmac_rx_stats_get(struct __vxge_hw_virtualpath *vpath, 1482 struct vxge_hw_xmac_vpath_rx_stats *vpath_rx_stats) 1483{ 1484 u64 *val64; 1485 enum vxge_hw_status status = VXGE_HW_OK; 1486 int i; 1487 u32 offset = VXGE_HW_STATS_VPATH_RX_OFFSET; 1488 val64 = (u64 *) vpath_rx_stats; 1489 1490 if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) { 1491 status = VXGE_HW_ERR_VPATH_NOT_OPEN; 1492 goto exit; 1493 } 1494 for (i = 0; i < sizeof(struct vxge_hw_xmac_vpath_rx_stats) / 8; i++) { 1495 status = __vxge_hw_vpath_stats_access(vpath, 1496 VXGE_HW_STATS_OP_READ, 1497 offset >> 3, val64); 1498 if (status != VXGE_HW_OK) 1499 goto exit; 1500 1501 offset += 8; 1502 val64++; 1503 } 1504exit: 1505 return status; 1506} 1507 1508/* 1509 * __vxge_hw_vpath_stats_get - Get the vpath hw statistics. 1510 */ 1511static enum vxge_hw_status 1512__vxge_hw_vpath_stats_get(struct __vxge_hw_virtualpath *vpath, 1513 struct vxge_hw_vpath_stats_hw_info *hw_stats) 1514{ 1515 u64 val64; 1516 enum vxge_hw_status status = VXGE_HW_OK; 1517 struct vxge_hw_vpath_reg __iomem *vp_reg; 1518 1519 if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) { 1520 status = VXGE_HW_ERR_VPATH_NOT_OPEN; 1521 goto exit; 1522 } 1523 vp_reg = vpath->vp_reg; 1524 1525 val64 = readq(&vp_reg->vpath_debug_stats0); 1526 hw_stats->ini_num_mwr_sent = 1527 (u32)VXGE_HW_VPATH_DEBUG_STATS0_GET_INI_NUM_MWR_SENT(val64); 1528 1529 val64 = readq(&vp_reg->vpath_debug_stats1); 1530 hw_stats->ini_num_mrd_sent = 1531 (u32)VXGE_HW_VPATH_DEBUG_STATS1_GET_INI_NUM_MRD_SENT(val64); 1532 1533 val64 = readq(&vp_reg->vpath_debug_stats2); 1534 hw_stats->ini_num_cpl_rcvd = 1535 (u32)VXGE_HW_VPATH_DEBUG_STATS2_GET_INI_NUM_CPL_RCVD(val64); 1536 1537 val64 = readq(&vp_reg->vpath_debug_stats3); 1538 hw_stats->ini_num_mwr_byte_sent = 1539 VXGE_HW_VPATH_DEBUG_STATS3_GET_INI_NUM_MWR_BYTE_SENT(val64); 1540 1541 val64 = readq(&vp_reg->vpath_debug_stats4); 1542 hw_stats->ini_num_cpl_byte_rcvd = 1543 VXGE_HW_VPATH_DEBUG_STATS4_GET_INI_NUM_CPL_BYTE_RCVD(val64); 1544 1545 val64 = readq(&vp_reg->vpath_debug_stats5); 1546 hw_stats->wrcrdtarb_xoff = 1547 (u32)VXGE_HW_VPATH_DEBUG_STATS5_GET_WRCRDTARB_XOFF(val64); 1548 1549 val64 = readq(&vp_reg->vpath_debug_stats6); 1550 hw_stats->rdcrdtarb_xoff = 1551 (u32)VXGE_HW_VPATH_DEBUG_STATS6_GET_RDCRDTARB_XOFF(val64); 1552 1553 val64 = readq(&vp_reg->vpath_genstats_count01); 1554 hw_stats->vpath_genstats_count0 = 1555 (u32)VXGE_HW_VPATH_GENSTATS_COUNT01_GET_PPIF_VPATH_GENSTATS_COUNT0( 1556 val64); 1557 1558 val64 = readq(&vp_reg->vpath_genstats_count01); 1559 hw_stats->vpath_genstats_count1 = 1560 (u32)VXGE_HW_VPATH_GENSTATS_COUNT01_GET_PPIF_VPATH_GENSTATS_COUNT1( 1561 val64); 1562 1563 val64 = readq(&vp_reg->vpath_genstats_count23); 1564 hw_stats->vpath_genstats_count2 = 1565 (u32)VXGE_HW_VPATH_GENSTATS_COUNT23_GET_PPIF_VPATH_GENSTATS_COUNT2( 1566 val64); 1567 1568 val64 = readq(&vp_reg->vpath_genstats_count01); 1569 hw_stats->vpath_genstats_count3 = 1570 (u32)VXGE_HW_VPATH_GENSTATS_COUNT23_GET_PPIF_VPATH_GENSTATS_COUNT3( 1571 val64); 1572 1573 val64 = readq(&vp_reg->vpath_genstats_count4); 1574 hw_stats->vpath_genstats_count4 = 1575 (u32)VXGE_HW_VPATH_GENSTATS_COUNT4_GET_PPIF_VPATH_GENSTATS_COUNT4( 1576 val64); 1577 1578 val64 = readq(&vp_reg->vpath_genstats_count5); 1579 hw_stats->vpath_genstats_count5 = 1580 (u32)VXGE_HW_VPATH_GENSTATS_COUNT5_GET_PPIF_VPATH_GENSTATS_COUNT5( 1581 val64); 1582 1583 status = __vxge_hw_vpath_xmac_tx_stats_get(vpath, &hw_stats->tx_stats); 1584 if (status != VXGE_HW_OK) 1585 goto exit; 1586 1587 status = __vxge_hw_vpath_xmac_rx_stats_get(vpath, &hw_stats->rx_stats); 1588 if (status != VXGE_HW_OK) 1589 goto exit; 1590 1591 VXGE_HW_VPATH_STATS_PIO_READ( 1592 VXGE_HW_STATS_VPATH_PROG_EVENT_VNUM0_OFFSET); 1593 1594 hw_stats->prog_event_vnum0 = 1595 (u32)VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM0(val64); 1596 1597 hw_stats->prog_event_vnum1 = 1598 (u32)VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM1(val64); 1599 1600 VXGE_HW_VPATH_STATS_PIO_READ( 1601 VXGE_HW_STATS_VPATH_PROG_EVENT_VNUM2_OFFSET); 1602 1603 hw_stats->prog_event_vnum2 = 1604 (u32)VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM2(val64); 1605 1606 hw_stats->prog_event_vnum3 = 1607 (u32)VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM3(val64); 1608 1609 val64 = readq(&vp_reg->rx_multi_cast_stats); 1610 hw_stats->rx_multi_cast_frame_discard = 1611 (u16)VXGE_HW_RX_MULTI_CAST_STATS_GET_FRAME_DISCARD(val64); 1612 1613 val64 = readq(&vp_reg->rx_frm_transferred); 1614 hw_stats->rx_frm_transferred = 1615 (u32)VXGE_HW_RX_FRM_TRANSFERRED_GET_RX_FRM_TRANSFERRED(val64); 1616 1617 val64 = readq(&vp_reg->rxd_returned); 1618 hw_stats->rxd_returned = 1619 (u16)VXGE_HW_RXD_RETURNED_GET_RXD_RETURNED(val64); 1620 1621 val64 = readq(&vp_reg->dbg_stats_rx_mpa); 1622 hw_stats->rx_mpa_len_fail_frms = 1623 (u16)VXGE_HW_DBG_STATS_GET_RX_MPA_LEN_FAIL_FRMS(val64); 1624 hw_stats->rx_mpa_mrk_fail_frms = 1625 (u16)VXGE_HW_DBG_STATS_GET_RX_MPA_MRK_FAIL_FRMS(val64); 1626 hw_stats->rx_mpa_crc_fail_frms = 1627 (u16)VXGE_HW_DBG_STATS_GET_RX_MPA_CRC_FAIL_FRMS(val64); 1628 1629 val64 = readq(&vp_reg->dbg_stats_rx_fau); 1630 hw_stats->rx_permitted_frms = 1631 (u16)VXGE_HW_DBG_STATS_GET_RX_FAU_RX_PERMITTED_FRMS(val64); 1632 hw_stats->rx_vp_reset_discarded_frms = 1633 (u16)VXGE_HW_DBG_STATS_GET_RX_FAU_RX_VP_RESET_DISCARDED_FRMS(val64); 1634 hw_stats->rx_wol_frms = 1635 (u16)VXGE_HW_DBG_STATS_GET_RX_FAU_RX_WOL_FRMS(val64); 1636 1637 val64 = readq(&vp_reg->tx_vp_reset_discarded_frms); 1638 hw_stats->tx_vp_reset_discarded_frms = 1639 (u16)VXGE_HW_TX_VP_RESET_DISCARDED_FRMS_GET_TX_VP_RESET_DISCARDED_FRMS( 1640 val64); 1641exit: 1642 return status; 1643} 1644 1645/* 1646 * vxge_hw_device_stats_get - Get the device hw statistics. 1647 * Returns the vpath h/w stats for the device. 1648 */ 1649enum vxge_hw_status 1650vxge_hw_device_stats_get(struct __vxge_hw_device *hldev, 1651 struct vxge_hw_device_stats_hw_info *hw_stats) 1652{ 1653 u32 i; 1654 enum vxge_hw_status status = VXGE_HW_OK; 1655 1656 for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) { 1657 if (!(hldev->vpaths_deployed & vxge_mBIT(i)) || 1658 (hldev->virtual_paths[i].vp_open == 1659 VXGE_HW_VP_NOT_OPEN)) 1660 continue; 1661 1662 memcpy(hldev->virtual_paths[i].hw_stats_sav, 1663 hldev->virtual_paths[i].hw_stats, 1664 sizeof(struct vxge_hw_vpath_stats_hw_info)); 1665 1666 status = __vxge_hw_vpath_stats_get( 1667 &hldev->virtual_paths[i], 1668 hldev->virtual_paths[i].hw_stats); 1669 } 1670 1671 memcpy(hw_stats, &hldev->stats.hw_dev_info_stats, 1672 sizeof(struct vxge_hw_device_stats_hw_info)); 1673 1674 return status; 1675} 1676 1677/* 1678 * vxge_hw_driver_stats_get - Get the device sw statistics. 1679 * Returns the vpath s/w stats for the device. 1680 */ 1681enum vxge_hw_status vxge_hw_driver_stats_get( 1682 struct __vxge_hw_device *hldev, 1683 struct vxge_hw_device_stats_sw_info *sw_stats) 1684{ 1685 enum vxge_hw_status status = VXGE_HW_OK; 1686 1687 memcpy(sw_stats, &hldev->stats.sw_dev_info_stats, 1688 sizeof(struct vxge_hw_device_stats_sw_info)); 1689 1690 return status; 1691} 1692 1693/* 1694 * vxge_hw_mrpcim_stats_access - Access the statistics from the given location 1695 * and offset and perform an operation 1696 * Get the statistics from the given location and offset. 1697 */ 1698enum vxge_hw_status 1699vxge_hw_mrpcim_stats_access(struct __vxge_hw_device *hldev, 1700 u32 operation, u32 location, u32 offset, u64 *stat) 1701{ 1702 u64 val64; 1703 enum vxge_hw_status status = VXGE_HW_OK; 1704 1705 status = __vxge_hw_device_is_privilaged(hldev->host_type, 1706 hldev->func_id); 1707 if (status != VXGE_HW_OK) 1708 goto exit; 1709 1710 val64 = VXGE_HW_XMAC_STATS_SYS_CMD_OP(operation) | 1711 VXGE_HW_XMAC_STATS_SYS_CMD_STROBE | 1712 VXGE_HW_XMAC_STATS_SYS_CMD_LOC_SEL(location) | 1713 VXGE_HW_XMAC_STATS_SYS_CMD_OFFSET_SEL(offset); 1714 1715 status = __vxge_hw_pio_mem_write64(val64, 1716 &hldev->mrpcim_reg->xmac_stats_sys_cmd, 1717 VXGE_HW_XMAC_STATS_SYS_CMD_STROBE, 1718 hldev->config.device_poll_millis); 1719 1720 if ((status == VXGE_HW_OK) && (operation == VXGE_HW_STATS_OP_READ)) 1721 *stat = readq(&hldev->mrpcim_reg->xmac_stats_sys_data); 1722 else 1723 *stat = 0; 1724exit: 1725 return status; 1726} 1727 1728/* 1729 * vxge_hw_device_xmac_aggr_stats_get - Get the Statistics on aggregate port 1730 * Get the Statistics on aggregate port 1731 */ 1732static enum vxge_hw_status 1733vxge_hw_device_xmac_aggr_stats_get(struct __vxge_hw_device *hldev, u32 port, 1734 struct vxge_hw_xmac_aggr_stats *aggr_stats) 1735{ 1736 u64 *val64; 1737 int i; 1738 u32 offset = VXGE_HW_STATS_AGGRn_OFFSET; 1739 enum vxge_hw_status status = VXGE_HW_OK; 1740 1741 val64 = (u64 *)aggr_stats; 1742 1743 status = __vxge_hw_device_is_privilaged(hldev->host_type, 1744 hldev->func_id); 1745 if (status != VXGE_HW_OK) 1746 goto exit; 1747 1748 for (i = 0; i < sizeof(struct vxge_hw_xmac_aggr_stats) / 8; i++) { 1749 status = vxge_hw_mrpcim_stats_access(hldev, 1750 VXGE_HW_STATS_OP_READ, 1751 VXGE_HW_STATS_LOC_AGGR, 1752 ((offset + (104 * port)) >> 3), val64); 1753 if (status != VXGE_HW_OK) 1754 goto exit; 1755 1756 offset += 8; 1757 val64++; 1758 } 1759exit: 1760 return status; 1761} 1762 1763/* 1764 * vxge_hw_device_xmac_port_stats_get - Get the Statistics on a port 1765 * Get the Statistics on port 1766 */ 1767static enum vxge_hw_status 1768vxge_hw_device_xmac_port_stats_get(struct __vxge_hw_device *hldev, u32 port, 1769 struct vxge_hw_xmac_port_stats *port_stats) 1770{ 1771 u64 *val64; 1772 enum vxge_hw_status status = VXGE_HW_OK; 1773 int i; 1774 u32 offset = 0x0; 1775 val64 = (u64 *) port_stats; 1776 1777 status = __vxge_hw_device_is_privilaged(hldev->host_type, 1778 hldev->func_id); 1779 if (status != VXGE_HW_OK) 1780 goto exit; 1781 1782 for (i = 0; i < sizeof(struct vxge_hw_xmac_port_stats) / 8; i++) { 1783 status = vxge_hw_mrpcim_stats_access(hldev, 1784 VXGE_HW_STATS_OP_READ, 1785 VXGE_HW_STATS_LOC_AGGR, 1786 ((offset + (608 * port)) >> 3), val64); 1787 if (status != VXGE_HW_OK) 1788 goto exit; 1789 1790 offset += 8; 1791 val64++; 1792 } 1793 1794exit: 1795 return status; 1796} 1797 1798/* 1799 * vxge_hw_device_xmac_stats_get - Get the XMAC Statistics 1800 * Get the XMAC Statistics 1801 */ 1802enum vxge_hw_status 1803vxge_hw_device_xmac_stats_get(struct __vxge_hw_device *hldev, 1804 struct vxge_hw_xmac_stats *xmac_stats) 1805{ 1806 enum vxge_hw_status status = VXGE_HW_OK; 1807 u32 i; 1808 1809 status = vxge_hw_device_xmac_aggr_stats_get(hldev, 1810 0, &xmac_stats->aggr_stats[0]); 1811 if (status != VXGE_HW_OK) 1812 goto exit; 1813 1814 status = vxge_hw_device_xmac_aggr_stats_get(hldev, 1815 1, &xmac_stats->aggr_stats[1]); 1816 if (status != VXGE_HW_OK) 1817 goto exit; 1818 1819 for (i = 0; i <= VXGE_HW_MAC_MAX_MAC_PORT_ID; i++) { 1820 1821 status = vxge_hw_device_xmac_port_stats_get(hldev, 1822 i, &xmac_stats->port_stats[i]); 1823 if (status != VXGE_HW_OK) 1824 goto exit; 1825 } 1826 1827 for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) { 1828 1829 if (!(hldev->vpaths_deployed & vxge_mBIT(i))) 1830 continue; 1831 1832 status = __vxge_hw_vpath_xmac_tx_stats_get( 1833 &hldev->virtual_paths[i], 1834 &xmac_stats->vpath_tx_stats[i]); 1835 if (status != VXGE_HW_OK) 1836 goto exit; 1837 1838 status = __vxge_hw_vpath_xmac_rx_stats_get( 1839 &hldev->virtual_paths[i], 1840 &xmac_stats->vpath_rx_stats[i]); 1841 if (status != VXGE_HW_OK) 1842 goto exit; 1843 } 1844exit: 1845 return status; 1846} 1847 1848/* 1849 * vxge_hw_device_debug_set - Set the debug module, level and timestamp 1850 * This routine is used to dynamically change the debug output 1851 */ 1852void vxge_hw_device_debug_set(struct __vxge_hw_device *hldev, 1853 enum vxge_debug_level level, u32 mask) 1854{ 1855 if (hldev == NULL) 1856 return; 1857 1858#if defined(VXGE_DEBUG_TRACE_MASK) || \ 1859 defined(VXGE_DEBUG_ERR_MASK) 1860 hldev->debug_module_mask = mask; 1861 hldev->debug_level = level; 1862#endif 1863 1864#if defined(VXGE_DEBUG_ERR_MASK) 1865 hldev->level_err = level & VXGE_ERR; 1866#endif 1867 1868#if defined(VXGE_DEBUG_TRACE_MASK) 1869 hldev->level_trace = level & VXGE_TRACE; 1870#endif 1871} 1872 1873/* 1874 * vxge_hw_device_error_level_get - Get the error level 1875 * This routine returns the current error level set 1876 */ 1877u32 vxge_hw_device_error_level_get(struct __vxge_hw_device *hldev) 1878{ 1879#if defined(VXGE_DEBUG_ERR_MASK) 1880 if (hldev == NULL) 1881 return VXGE_ERR; 1882 else 1883 return hldev->level_err; 1884#else 1885 return 0; 1886#endif 1887} 1888 1889/* 1890 * vxge_hw_device_trace_level_get - Get the trace level 1891 * This routine returns the current trace level set 1892 */ 1893u32 vxge_hw_device_trace_level_get(struct __vxge_hw_device *hldev) 1894{ 1895#if defined(VXGE_DEBUG_TRACE_MASK) 1896 if (hldev == NULL) 1897 return VXGE_TRACE; 1898 else 1899 return hldev->level_trace; 1900#else 1901 return 0; 1902#endif 1903} 1904 1905/* 1906 * vxge_hw_getpause_data -Pause frame frame generation and reception. 1907 * Returns the Pause frame generation and reception capability of the NIC. 1908 */ 1909enum vxge_hw_status vxge_hw_device_getpause_data(struct __vxge_hw_device *hldev, 1910 u32 port, u32 *tx, u32 *rx) 1911{ 1912 u64 val64; 1913 enum vxge_hw_status status = VXGE_HW_OK; 1914 1915 if ((hldev == NULL) || (hldev->magic != VXGE_HW_DEVICE_MAGIC)) { 1916 status = VXGE_HW_ERR_INVALID_DEVICE; 1917 goto exit; 1918 } 1919 1920 if (port > VXGE_HW_MAC_MAX_MAC_PORT_ID) { 1921 status = VXGE_HW_ERR_INVALID_PORT; 1922 goto exit; 1923 } 1924 1925 if (!(hldev->access_rights & VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM)) { 1926 status = VXGE_HW_ERR_PRIVILAGED_OPEARATION; 1927 goto exit; 1928 } 1929 1930 val64 = readq(&hldev->mrpcim_reg->rxmac_pause_cfg_port[port]); 1931 if (val64 & VXGE_HW_RXMAC_PAUSE_CFG_PORT_GEN_EN) 1932 *tx = 1; 1933 if (val64 & VXGE_HW_RXMAC_PAUSE_CFG_PORT_RCV_EN) 1934 *rx = 1; 1935exit: 1936 return status; 1937} 1938 1939/* 1940 * vxge_hw_device_setpause_data - set/reset pause frame generation. 1941 * It can be used to set or reset Pause frame generation or reception 1942 * support of the NIC. 1943 */ 1944enum vxge_hw_status vxge_hw_device_setpause_data(struct __vxge_hw_device *hldev, 1945 u32 port, u32 tx, u32 rx) 1946{ 1947 u64 val64; 1948 enum vxge_hw_status status = VXGE_HW_OK; 1949 1950 if ((hldev == NULL) || (hldev->magic != VXGE_HW_DEVICE_MAGIC)) { 1951 status = VXGE_HW_ERR_INVALID_DEVICE; 1952 goto exit; 1953 } 1954 1955 if (port > VXGE_HW_MAC_MAX_MAC_PORT_ID) { 1956 status = VXGE_HW_ERR_INVALID_PORT; 1957 goto exit; 1958 } 1959 1960 status = __vxge_hw_device_is_privilaged(hldev->host_type, 1961 hldev->func_id); 1962 if (status != VXGE_HW_OK) 1963 goto exit; 1964 1965 val64 = readq(&hldev->mrpcim_reg->rxmac_pause_cfg_port[port]); 1966 if (tx) 1967 val64 |= VXGE_HW_RXMAC_PAUSE_CFG_PORT_GEN_EN; 1968 else 1969 val64 &= ~VXGE_HW_RXMAC_PAUSE_CFG_PORT_GEN_EN; 1970 if (rx) 1971 val64 |= VXGE_HW_RXMAC_PAUSE_CFG_PORT_RCV_EN; 1972 else 1973 val64 &= ~VXGE_HW_RXMAC_PAUSE_CFG_PORT_RCV_EN; 1974 1975 writeq(val64, &hldev->mrpcim_reg->rxmac_pause_cfg_port[port]); 1976exit: 1977 return status; 1978} 1979 1980u16 vxge_hw_device_link_width_get(struct __vxge_hw_device *hldev) 1981{ 1982 struct pci_dev *dev = hldev->pdev; 1983 u16 lnk; 1984 1985 pci_read_config_word(dev, dev->pcie_cap + PCI_EXP_LNKSTA, &lnk); 1986 return (lnk & VXGE_HW_PCI_EXP_LNKCAP_LNK_WIDTH) >> 4; 1987} 1988 1989/* 1990 * __vxge_hw_ring_block_memblock_idx - Return the memblock index 1991 * This function returns the index of memory block 1992 */ 1993static inline u32 1994__vxge_hw_ring_block_memblock_idx(u8 *block) 1995{ 1996 return (u32)*((u64 *)(block + VXGE_HW_RING_MEMBLOCK_IDX_OFFSET)); 1997} 1998 1999/* 2000 * __vxge_hw_ring_block_memblock_idx_set - Sets the memblock index 2001 * This function sets index to a memory block 2002 */ 2003static inline void 2004__vxge_hw_ring_block_memblock_idx_set(u8 *block, u32 memblock_idx) 2005{ 2006 *((u64 *)(block + VXGE_HW_RING_MEMBLOCK_IDX_OFFSET)) = memblock_idx; 2007} 2008 2009/* 2010 * __vxge_hw_ring_block_next_pointer_set - Sets the next block pointer 2011 * in RxD block 2012 * Sets the next block pointer in RxD block 2013 */ 2014static inline void 2015__vxge_hw_ring_block_next_pointer_set(u8 *block, dma_addr_t dma_next) 2016{ 2017 *((u64 *)(block + VXGE_HW_RING_NEXT_BLOCK_POINTER_OFFSET)) = dma_next; 2018} 2019 2020/* 2021 * __vxge_hw_ring_first_block_address_get - Returns the dma address of the 2022 * first block 2023 * Returns the dma address of the first RxD block 2024 */ 2025static u64 __vxge_hw_ring_first_block_address_get(struct __vxge_hw_ring *ring) 2026{ 2027 struct vxge_hw_mempool_dma *dma_object; 2028 2029 dma_object = ring->mempool->memblocks_dma_arr; 2030 vxge_assert(dma_object != NULL); 2031 2032 return dma_object->addr; 2033} 2034 2035/* 2036 * __vxge_hw_ring_item_dma_addr - Return the dma address of an item 2037 * This function returns the dma address of a given item 2038 */ 2039static dma_addr_t __vxge_hw_ring_item_dma_addr(struct vxge_hw_mempool *mempoolh, 2040 void *item) 2041{ 2042 u32 memblock_idx; 2043 void *memblock; 2044 struct vxge_hw_mempool_dma *memblock_dma_object; 2045 ptrdiff_t dma_item_offset; 2046 2047 /* get owner memblock index */ 2048 memblock_idx = __vxge_hw_ring_block_memblock_idx(item); 2049 2050 /* get owner memblock by memblock index */ 2051 memblock = mempoolh->memblocks_arr[memblock_idx]; 2052 2053 /* get memblock DMA object by memblock index */ 2054 memblock_dma_object = mempoolh->memblocks_dma_arr + memblock_idx; 2055 2056 /* calculate offset in the memblock of this item */ 2057 dma_item_offset = (u8 *)item - (u8 *)memblock; 2058 2059 return memblock_dma_object->addr + dma_item_offset; 2060} 2061 2062/* 2063 * __vxge_hw_ring_rxdblock_link - Link the RxD blocks 2064 * This function returns the dma address of a given item 2065 */ 2066static void __vxge_hw_ring_rxdblock_link(struct vxge_hw_mempool *mempoolh, 2067 struct __vxge_hw_ring *ring, u32 from, 2068 u32 to) 2069{ 2070 u8 *to_item , *from_item; 2071 dma_addr_t to_dma; 2072 2073 /* get "from" RxD block */ 2074 from_item = mempoolh->items_arr[from]; 2075 vxge_assert(from_item); 2076 2077 /* get "to" RxD block */ 2078 to_item = mempoolh->items_arr[to]; 2079 vxge_assert(to_item); 2080 2081 /* return address of the beginning of previous RxD block */ 2082 to_dma = __vxge_hw_ring_item_dma_addr(mempoolh, to_item); 2083 2084 /* set next pointer for this RxD block to point on 2085 * previous item's DMA start address */ 2086 __vxge_hw_ring_block_next_pointer_set(from_item, to_dma); 2087} 2088 2089/* 2090 * __vxge_hw_ring_mempool_item_alloc - Allocate List blocks for RxD 2091 * block callback 2092 * This function is callback passed to __vxge_hw_mempool_create to create memory 2093 * pool for RxD block 2094 */ 2095static void 2096__vxge_hw_ring_mempool_item_alloc(struct vxge_hw_mempool *mempoolh, 2097 u32 memblock_index, 2098 struct vxge_hw_mempool_dma *dma_object, 2099 u32 index, u32 is_last) 2100{ 2101 u32 i; 2102 void *item = mempoolh->items_arr[index]; 2103 struct __vxge_hw_ring *ring = 2104 (struct __vxge_hw_ring *)mempoolh->userdata; 2105 2106 /* format rxds array */ 2107 for (i = 0; i < ring->rxds_per_block; i++) { 2108 void *rxdblock_priv; 2109 void *uld_priv; 2110 struct vxge_hw_ring_rxd_1 *rxdp; 2111 2112 u32 reserve_index = ring->channel.reserve_ptr - 2113 (index * ring->rxds_per_block + i + 1); 2114 u32 memblock_item_idx; 2115 2116 ring->channel.reserve_arr[reserve_index] = ((u8 *)item) + 2117 i * ring->rxd_size; 2118 2119 /* Note: memblock_item_idx is index of the item within 2120 * the memblock. For instance, in case of three RxD-blocks 2121 * per memblock this value can be 0, 1 or 2. */ 2122 rxdblock_priv = __vxge_hw_mempool_item_priv(mempoolh, 2123 memblock_index, item, 2124 &memblock_item_idx); 2125 2126 rxdp = ring->channel.reserve_arr[reserve_index]; 2127 2128 uld_priv = ((u8 *)rxdblock_priv + ring->rxd_priv_size * i); 2129 2130 /* pre-format Host_Control */ 2131 rxdp->host_control = (u64)(size_t)uld_priv; 2132 } 2133 2134 __vxge_hw_ring_block_memblock_idx_set(item, memblock_index); 2135 2136 if (is_last) { 2137 /* link last one with first one */ 2138 __vxge_hw_ring_rxdblock_link(mempoolh, ring, index, 0); 2139 } 2140 2141 if (index > 0) { 2142 /* link this RxD block with previous one */ 2143 __vxge_hw_ring_rxdblock_link(mempoolh, ring, index - 1, index); 2144 } 2145} 2146 2147/* 2148 * __vxge_hw_ring_replenish - Initial replenish of RxDs 2149 * This function replenishes the RxDs from reserve array to work array 2150 */ 2151enum vxge_hw_status 2152vxge_hw_ring_replenish(struct __vxge_hw_ring *ring) 2153{ 2154 void *rxd; 2155 struct __vxge_hw_channel *channel; 2156 enum vxge_hw_status status = VXGE_HW_OK; 2157 2158 channel = &ring->channel; 2159 2160 while (vxge_hw_channel_dtr_count(channel) > 0) { 2161 2162 status = vxge_hw_ring_rxd_reserve(ring, &rxd); 2163 2164 vxge_assert(status == VXGE_HW_OK); 2165 2166 if (ring->rxd_init) { 2167 status = ring->rxd_init(rxd, channel->userdata); 2168 if (status != VXGE_HW_OK) { 2169 vxge_hw_ring_rxd_free(ring, rxd); 2170 goto exit; 2171 } 2172 } 2173 2174 vxge_hw_ring_rxd_post(ring, rxd); 2175 } 2176 status = VXGE_HW_OK; 2177exit: 2178 return status; 2179} 2180 2181/* 2182 * __vxge_hw_channel_allocate - Allocate memory for channel 2183 * This function allocates required memory for the channel and various arrays 2184 * in the channel 2185 */ 2186static struct __vxge_hw_channel * 2187__vxge_hw_channel_allocate(struct __vxge_hw_vpath_handle *vph, 2188 enum __vxge_hw_channel_type type, 2189 u32 length, u32 per_dtr_space, 2190 void *userdata) 2191{ 2192 struct __vxge_hw_channel *channel; 2193 struct __vxge_hw_device *hldev; 2194 int size = 0; 2195 u32 vp_id; 2196 2197 hldev = vph->vpath->hldev; 2198 vp_id = vph->vpath->vp_id; 2199 2200 switch (type) { 2201 case VXGE_HW_CHANNEL_TYPE_FIFO: 2202 size = sizeof(struct __vxge_hw_fifo); 2203 break; 2204 case VXGE_HW_CHANNEL_TYPE_RING: 2205 size = sizeof(struct __vxge_hw_ring); 2206 break; 2207 default: 2208 break; 2209 } 2210 2211 channel = kzalloc(size, GFP_KERNEL); 2212 if (channel == NULL) 2213 goto exit0; 2214 INIT_LIST_HEAD(&channel->item); 2215 2216 channel->common_reg = hldev->common_reg; 2217 channel->first_vp_id = hldev->first_vp_id; 2218 channel->type = type; 2219 channel->devh = hldev; 2220 channel->vph = vph; 2221 channel->userdata = userdata; 2222 channel->per_dtr_space = per_dtr_space; 2223 channel->length = length; 2224 channel->vp_id = vp_id; 2225 2226 channel->work_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL); 2227 if (channel->work_arr == NULL) 2228 goto exit1; 2229 2230 channel->free_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL); 2231 if (channel->free_arr == NULL) 2232 goto exit1; 2233 channel->free_ptr = length; 2234 2235 channel->reserve_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL); 2236 if (channel->reserve_arr == NULL) 2237 goto exit1; 2238 channel->reserve_ptr = length; 2239 channel->reserve_top = 0; 2240 2241 channel->orig_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL); 2242 if (channel->orig_arr == NULL) 2243 goto exit1; 2244 2245 return channel; 2246exit1: 2247 __vxge_hw_channel_free(channel); 2248 2249exit0: 2250 return NULL; 2251} 2252 2253/* 2254 * vxge_hw_blockpool_block_add - callback for vxge_os_dma_malloc_async 2255 * Adds a block to block pool 2256 */ 2257static void vxge_hw_blockpool_block_add(struct __vxge_hw_device *devh, 2258 void *block_addr, 2259 u32 length, 2260 struct pci_dev *dma_h, 2261 struct pci_dev *acc_handle) 2262{ 2263 struct __vxge_hw_blockpool *blockpool; 2264 struct __vxge_hw_blockpool_entry *entry = NULL; 2265 dma_addr_t dma_addr; 2266 enum vxge_hw_status status = VXGE_HW_OK; 2267 u32 req_out; 2268 2269 blockpool = &devh->block_pool; 2270 2271 if (block_addr == NULL) { 2272 blockpool->req_out--; 2273 status = VXGE_HW_FAIL; 2274 goto exit; 2275 } 2276 2277 dma_addr = pci_map_single(devh->pdev, block_addr, length, 2278 PCI_DMA_BIDIRECTIONAL); 2279 2280 if (unlikely(pci_dma_mapping_error(devh->pdev, dma_addr))) { 2281 vxge_os_dma_free(devh->pdev, block_addr, &acc_handle); 2282 blockpool->req_out--; 2283 status = VXGE_HW_FAIL; 2284 goto exit; 2285 } 2286 2287 if (!list_empty(&blockpool->free_entry_list)) 2288 entry = (struct __vxge_hw_blockpool_entry *) 2289 list_first_entry(&blockpool->free_entry_list, 2290 struct __vxge_hw_blockpool_entry, 2291 item); 2292 2293 if (entry == NULL) 2294 entry = vmalloc(sizeof(struct __vxge_hw_blockpool_entry)); 2295 else 2296 list_del(&entry->item); 2297 2298 if (entry != NULL) { 2299 entry->length = length; 2300 entry->memblock = block_addr; 2301 entry->dma_addr = dma_addr; 2302 entry->acc_handle = acc_handle; 2303 entry->dma_handle = dma_h; 2304 list_add(&entry->item, &blockpool->free_block_list); 2305 blockpool->pool_size++; 2306 status = VXGE_HW_OK; 2307 } else 2308 status = VXGE_HW_ERR_OUT_OF_MEMORY; 2309 2310 blockpool->req_out--; 2311 2312 req_out = blockpool->req_out; 2313exit: 2314 return; 2315} 2316 2317static inline void 2318vxge_os_dma_malloc_async(struct pci_dev *pdev, void *devh, unsigned long size) 2319{ 2320 gfp_t flags; 2321 void *vaddr; 2322 2323 if (in_interrupt()) 2324 flags = GFP_ATOMIC | GFP_DMA; 2325 else 2326 flags = GFP_KERNEL | GFP_DMA; 2327 2328 vaddr = kmalloc((size), flags); 2329 2330 vxge_hw_blockpool_block_add(devh, vaddr, size, pdev, pdev); 2331} 2332 2333/* 2334 * __vxge_hw_blockpool_blocks_add - Request additional blocks 2335 */ 2336static 2337void __vxge_hw_blockpool_blocks_add(struct __vxge_hw_blockpool *blockpool) 2338{ 2339 u32 nreq = 0, i; 2340 2341 if ((blockpool->pool_size + blockpool->req_out) < 2342 VXGE_HW_MIN_DMA_BLOCK_POOL_SIZE) { 2343 nreq = VXGE_HW_INCR_DMA_BLOCK_POOL_SIZE; 2344 blockpool->req_out += nreq; 2345 } 2346 2347 for (i = 0; i < nreq; i++) 2348 vxge_os_dma_malloc_async( 2349 ((struct __vxge_hw_device *)blockpool->hldev)->pdev, 2350 blockpool->hldev, VXGE_HW_BLOCK_SIZE); 2351} 2352 2353/* 2354 * __vxge_hw_blockpool_malloc - Allocate a memory block from pool 2355 * Allocates a block of memory of given size, either from block pool 2356 * or by calling vxge_os_dma_malloc() 2357 */ 2358static void *__vxge_hw_blockpool_malloc(struct __vxge_hw_device *devh, u32 size, 2359 struct vxge_hw_mempool_dma *dma_object) 2360{ 2361 struct __vxge_hw_blockpool_entry *entry = NULL; 2362 struct __vxge_hw_blockpool *blockpool; 2363 void *memblock = NULL; 2364 enum vxge_hw_status status = VXGE_HW_OK; 2365 2366 blockpool = &devh->block_pool; 2367 2368 if (size != blockpool->block_size) { 2369 2370 memblock = vxge_os_dma_malloc(devh->pdev, size, 2371 &dma_object->handle, 2372 &dma_object->acc_handle); 2373 2374 if (memblock == NULL) { 2375 status = VXGE_HW_ERR_OUT_OF_MEMORY; 2376 goto exit; 2377 } 2378 2379 dma_object->addr = pci_map_single(devh->pdev, memblock, size, 2380 PCI_DMA_BIDIRECTIONAL); 2381 2382 if (unlikely(pci_dma_mapping_error(devh->pdev, 2383 dma_object->addr))) { 2384 vxge_os_dma_free(devh->pdev, memblock, 2385 &dma_object->acc_handle); 2386 status = VXGE_HW_ERR_OUT_OF_MEMORY; 2387 goto exit; 2388 } 2389 2390 } else { 2391 2392 if (!list_empty(&blockpool->free_block_list)) 2393 entry = (struct __vxge_hw_blockpool_entry *) 2394 list_first_entry(&blockpool->free_block_list, 2395 struct __vxge_hw_blockpool_entry, 2396 item); 2397 2398 if (entry != NULL) { 2399 list_del(&entry->item); 2400 dma_object->addr = entry->dma_addr; 2401 dma_object->handle = entry->dma_handle; 2402 dma_object->acc_handle = entry->acc_handle; 2403 memblock = entry->memblock; 2404 2405 list_add(&entry->item, 2406 &blockpool->free_entry_list); 2407 blockpool->pool_size--; 2408 } 2409 2410 if (memblock != NULL) 2411 __vxge_hw_blockpool_blocks_add(blockpool); 2412 } 2413exit: 2414 return memblock; 2415} 2416 2417/* 2418 * __vxge_hw_blockpool_blocks_remove - Free additional blocks 2419 */ 2420static void 2421__vxge_hw_blockpool_blocks_remove(struct __vxge_hw_blockpool *blockpool) 2422{ 2423 struct list_head *p, *n; 2424 2425 list_for_each_safe(p, n, &blockpool->free_block_list) { 2426 2427 if (blockpool->pool_size < blockpool->pool_max) 2428 break; 2429 2430 pci_unmap_single( 2431 ((struct __vxge_hw_device *)blockpool->hldev)->pdev, 2432 ((struct __vxge_hw_blockpool_entry *)p)->dma_addr, 2433 ((struct __vxge_hw_blockpool_entry *)p)->length, 2434 PCI_DMA_BIDIRECTIONAL); 2435 2436 vxge_os_dma_free( 2437 ((struct __vxge_hw_device *)blockpool->hldev)->pdev, 2438 ((struct __vxge_hw_blockpool_entry *)p)->memblock, 2439 &((struct __vxge_hw_blockpool_entry *)p)->acc_handle); 2440 2441 list_del(&((struct __vxge_hw_blockpool_entry *)p)->item); 2442 2443 list_add(p, &blockpool->free_entry_list); 2444 2445 blockpool->pool_size--; 2446 2447 } 2448} 2449 2450/* 2451 * __vxge_hw_blockpool_free - Frees the memory allcoated with 2452 * __vxge_hw_blockpool_malloc 2453 */ 2454static void __vxge_hw_blockpool_free(struct __vxge_hw_device *devh, 2455 void *memblock, u32 size, 2456 struct vxge_hw_mempool_dma *dma_object) 2457{ 2458 struct __vxge_hw_blockpool_entry *entry = NULL; 2459 struct __vxge_hw_blockpool *blockpool; 2460 enum vxge_hw_status status = VXGE_HW_OK; 2461 2462 blockpool = &devh->block_pool; 2463 2464 if (size != blockpool->block_size) { 2465 pci_unmap_single(devh->pdev, dma_object->addr, size, 2466 PCI_DMA_BIDIRECTIONAL); 2467 vxge_os_dma_free(devh->pdev, memblock, &dma_object->acc_handle); 2468 } else { 2469 2470 if (!list_empty(&blockpool->free_entry_list)) 2471 entry = (struct __vxge_hw_blockpool_entry *) 2472 list_first_entry(&blockpool->free_entry_list, 2473 struct __vxge_hw_blockpool_entry, 2474 item); 2475 2476 if (entry == NULL) 2477 entry = vmalloc(sizeof( 2478 struct __vxge_hw_blockpool_entry)); 2479 else 2480 list_del(&entry->item); 2481 2482 if (entry != NULL) { 2483 entry->length = size; 2484 entry->memblock = memblock; 2485 entry->dma_addr = dma_object->addr; 2486 entry->acc_handle = dma_object->acc_handle; 2487 entry->dma_handle = dma_object->handle; 2488 list_add(&entry->item, 2489 &blockpool->free_block_list); 2490 blockpool->pool_size++; 2491 status = VXGE_HW_OK; 2492 } else 2493 status = VXGE_HW_ERR_OUT_OF_MEMORY; 2494 2495 if (status == VXGE_HW_OK) 2496 __vxge_hw_blockpool_blocks_remove(blockpool); 2497 } 2498} 2499 2500/* 2501 * vxge_hw_mempool_destroy 2502 */ 2503static void __vxge_hw_mempool_destroy(struct vxge_hw_mempool *mempool) 2504{ 2505 u32 i, j; 2506 struct __vxge_hw_device *devh = mempool->devh; 2507 2508 for (i = 0; i < mempool->memblocks_allocated; i++) { 2509 struct vxge_hw_mempool_dma *dma_object; 2510 2511 vxge_assert(mempool->memblocks_arr[i]); 2512 vxge_assert(mempool->memblocks_dma_arr + i); 2513 2514 dma_object = mempool->memblocks_dma_arr + i; 2515 2516 for (j = 0; j < mempool->items_per_memblock; j++) { 2517 u32 index = i * mempool->items_per_memblock + j; 2518 2519 /* to skip last partially filled(if any) memblock */ 2520 if (index >= mempool->items_current) 2521 break; 2522 } 2523 2524 vfree(mempool->memblocks_priv_arr[i]); 2525 2526 __vxge_hw_blockpool_free(devh, mempool->memblocks_arr[i], 2527 mempool->memblock_size, dma_object); 2528 } 2529 2530 vfree(mempool->items_arr); 2531 vfree(mempool->memblocks_dma_arr); 2532 vfree(mempool->memblocks_priv_arr); 2533 vfree(mempool->memblocks_arr); 2534 vfree(mempool); 2535} 2536 2537/* 2538 * __vxge_hw_mempool_grow 2539 * Will resize mempool up to %num_allocate value. 2540 */ 2541static enum vxge_hw_status 2542__vxge_hw_mempool_grow(struct vxge_hw_mempool *mempool, u32 num_allocate, 2543 u32 *num_allocated) 2544{ 2545 u32 i, first_time = mempool->memblocks_allocated == 0 ? 1 : 0; 2546 u32 n_items = mempool->items_per_memblock; 2547 u32 start_block_idx = mempool->memblocks_allocated; 2548 u32 end_block_idx = mempool->memblocks_allocated + num_allocate; 2549 enum vxge_hw_status status = VXGE_HW_OK; 2550 2551 *num_allocated = 0; 2552 2553 if (end_block_idx > mempool->memblocks_max) { 2554 status = VXGE_HW_ERR_OUT_OF_MEMORY; 2555 goto exit; 2556 } 2557 2558 for (i = start_block_idx; i < end_block_idx; i++) { 2559 u32 j; 2560 u32 is_last = ((end_block_idx - 1) == i); 2561 struct vxge_hw_mempool_dma *dma_object = 2562 mempool->memblocks_dma_arr + i; 2563 void *the_memblock; 2564 2565 /* allocate memblock's private part. Each DMA memblock 2566 * has a space allocated for item's private usage upon 2567 * mempool's user request. Each time mempool grows, it will 2568 * allocate new memblock and its private part at once. 2569 * This helps to minimize memory usage a lot. */ 2570 mempool->memblocks_priv_arr[i] = 2571 vzalloc(mempool->items_priv_size * n_items); 2572 if (mempool->memblocks_priv_arr[i] == NULL) { 2573 status = VXGE_HW_ERR_OUT_OF_MEMORY; 2574 goto exit; 2575 } 2576 2577 /* allocate DMA-capable memblock */ 2578 mempool->memblocks_arr[i] = 2579 __vxge_hw_blockpool_malloc(mempool->devh, 2580 mempool->memblock_size, dma_object); 2581 if (mempool->memblocks_arr[i] == NULL) { 2582 vfree(mempool->memblocks_priv_arr[i]); 2583 status = VXGE_HW_ERR_OUT_OF_MEMORY; 2584 goto exit; 2585 } 2586 2587 (*num_allocated)++; 2588 mempool->memblocks_allocated++; 2589 2590 memset(mempool->memblocks_arr[i], 0, mempool->memblock_size); 2591 2592 the_memblock = mempool->memblocks_arr[i]; 2593 2594 /* fill the items hash array */ 2595 for (j = 0; j < n_items; j++) { 2596 u32 index = i * n_items + j; 2597 2598 if (first_time && index >= mempool->items_initial) 2599 break; 2600 2601 mempool->items_arr[index] = 2602 ((char *)the_memblock + j*mempool->item_size); 2603 2604 /* let caller to do more job on each item */ 2605 if (mempool->item_func_alloc != NULL) 2606 mempool->item_func_alloc(mempool, i, 2607 dma_object, index, is_last); 2608 2609 mempool->items_current = index + 1; 2610 } 2611 2612 if (first_time && mempool->items_current == 2613 mempool->items_initial) 2614 break; 2615 } 2616exit: 2617 return status; 2618} 2619 2620/* 2621 * vxge_hw_mempool_create 2622 * This function will create memory pool object. Pool may grow but will 2623 * never shrink. Pool consists of number of dynamically allocated blocks 2624 * with size enough to hold %items_initial number of items. Memory is 2625 * DMA-able but client must map/unmap before interoperating with the device. 2626 */ 2627static struct vxge_hw_mempool * 2628__vxge_hw_mempool_create(struct __vxge_hw_device *devh, 2629 u32 memblock_size, 2630 u32 item_size, 2631 u32 items_priv_size, 2632 u32 items_initial, 2633 u32 items_max, 2634 const struct vxge_hw_mempool_cbs *mp_callback, 2635 void *userdata) 2636{ 2637 enum vxge_hw_status status = VXGE_HW_OK; 2638 u32 memblocks_to_allocate; 2639 struct vxge_hw_mempool *mempool = NULL; 2640 u32 allocated; 2641 2642 if (memblock_size < item_size) { 2643 status = VXGE_HW_FAIL; 2644 goto exit; 2645 } 2646 2647 mempool = vzalloc(sizeof(struct vxge_hw_mempool)); 2648 if (mempool == NULL) { 2649 status = VXGE_HW_ERR_OUT_OF_MEMORY; 2650 goto exit; 2651 } 2652 2653 mempool->devh = devh; 2654 mempool->memblock_size = memblock_size; 2655 mempool->items_max = items_max; 2656 mempool->items_initial = items_initial; 2657 mempool->item_size = item_size; 2658 mempool->items_priv_size = items_priv_size; 2659 mempool->item_func_alloc = mp_callback->item_func_alloc; 2660 mempool->userdata = userdata; 2661 2662 mempool->memblocks_allocated = 0; 2663 2664 mempool->items_per_memblock = memblock_size / item_size; 2665 2666 mempool->memblocks_max = (items_max + mempool->items_per_memblock - 1) / 2667 mempool->items_per_memblock; 2668 2669 /* allocate array of memblocks */ 2670 mempool->memblocks_arr = 2671 vzalloc(sizeof(void *) * mempool->memblocks_max); 2672 if (mempool->memblocks_arr == NULL) { 2673 __vxge_hw_mempool_destroy(mempool); 2674 status = VXGE_HW_ERR_OUT_OF_MEMORY; 2675 mempool = NULL; 2676 goto exit; 2677 } 2678 2679 /* allocate array of private parts of items per memblocks */ 2680 mempool->memblocks_priv_arr = 2681 vzalloc(sizeof(void *) * mempool->memblocks_max); 2682 if (mempool->memblocks_priv_arr == NULL) { 2683 __vxge_hw_mempool_destroy(mempool); 2684 status = VXGE_HW_ERR_OUT_OF_MEMORY; 2685 mempool = NULL; 2686 goto exit; 2687 } 2688 2689 /* allocate array of memblocks DMA objects */ 2690 mempool->memblocks_dma_arr = 2691 vzalloc(sizeof(struct vxge_hw_mempool_dma) * 2692 mempool->memblocks_max); 2693 if (mempool->memblocks_dma_arr == NULL) { 2694 __vxge_hw_mempool_destroy(mempool); 2695 status = VXGE_HW_ERR_OUT_OF_MEMORY; 2696 mempool = NULL; 2697 goto exit; 2698 } 2699 2700 /* allocate hash array of items */ 2701 mempool->items_arr = vzalloc(sizeof(void *) * mempool->items_max); 2702 if (mempool->items_arr == NULL) { 2703 __vxge_hw_mempool_destroy(mempool); 2704 status = VXGE_HW_ERR_OUT_OF_MEMORY; 2705 mempool = NULL; 2706 goto exit; 2707 } 2708 2709 /* calculate initial number of memblocks */ 2710 memblocks_to_allocate = (mempool->items_initial + 2711 mempool->items_per_memblock - 1) / 2712 mempool->items_per_memblock; 2713 2714 /* pre-allocate the mempool */ 2715 status = __vxge_hw_mempool_grow(mempool, memblocks_to_allocate, 2716 &allocated); 2717 if (status != VXGE_HW_OK) { 2718 __vxge_hw_mempool_destroy(mempool); 2719 status = VXGE_HW_ERR_OUT_OF_MEMORY; 2720 mempool = NULL; 2721 goto exit; 2722 } 2723 2724exit: 2725 return mempool; 2726} 2727 2728/* 2729 * __vxge_hw_ring_abort - Returns the RxD 2730 * This function terminates the RxDs of ring 2731 */ 2732static enum vxge_hw_status __vxge_hw_ring_abort(struct __vxge_hw_ring *ring) 2733{ 2734 void *rxdh; 2735 struct __vxge_hw_channel *channel; 2736 2737 channel = &ring->channel; 2738 2739 for (;;) { 2740 vxge_hw_channel_dtr_try_complete(channel, &rxdh); 2741 2742 if (rxdh == NULL) 2743 break; 2744 2745 vxge_hw_channel_dtr_complete(channel); 2746 2747 if (ring->rxd_term) 2748 ring->rxd_term(rxdh, VXGE_HW_RXD_STATE_POSTED, 2749 channel->userdata); 2750 2751 vxge_hw_channel_dtr_free(channel, rxdh); 2752 } 2753 2754 return VXGE_HW_OK; 2755} 2756 2757/* 2758 * __vxge_hw_ring_reset - Resets the ring 2759 * This function resets the ring during vpath reset operation 2760 */ 2761static enum vxge_hw_status __vxge_hw_ring_reset(struct __vxge_hw_ring *ring) 2762{ 2763 enum vxge_hw_status status = VXGE_HW_OK; 2764 struct __vxge_hw_channel *channel; 2765 2766 channel = &ring->channel; 2767 2768 __vxge_hw_ring_abort(ring); 2769 2770 status = __vxge_hw_channel_reset(channel); 2771 2772 if (status != VXGE_HW_OK) 2773 goto exit; 2774 2775 if (ring->rxd_init) { 2776 status = vxge_hw_ring_replenish(ring); 2777 if (status != VXGE_HW_OK) 2778 goto exit; 2779 } 2780exit: 2781 return status; 2782} 2783 2784/* 2785 * __vxge_hw_ring_delete - Removes the ring 2786 * This function freeup the memory pool and removes the ring 2787 */ 2788static enum vxge_hw_status 2789__vxge_hw_ring_delete(struct __vxge_hw_vpath_handle *vp) 2790{ 2791 struct __vxge_hw_ring *ring = vp->vpath->ringh; 2792 2793 __vxge_hw_ring_abort(ring); 2794 2795 if (ring->mempool) 2796 __vxge_hw_mempool_destroy(ring->mempool); 2797 2798 vp->vpath->ringh = NULL; 2799 __vxge_hw_channel_free(&ring->channel); 2800 2801 return VXGE_HW_OK; 2802} 2803 2804/* 2805 * __vxge_hw_ring_create - Create a Ring 2806 * This function creates Ring and initializes it. 2807 */ 2808static enum vxge_hw_status 2809__vxge_hw_ring_create(struct __vxge_hw_vpath_handle *vp, 2810 struct vxge_hw_ring_attr *attr) 2811{ 2812 enum vxge_hw_status status = VXGE_HW_OK; 2813 struct __vxge_hw_ring *ring; 2814 u32 ring_length; 2815 struct vxge_hw_ring_config *config; 2816 struct __vxge_hw_device *hldev; 2817 u32 vp_id; 2818 static const struct vxge_hw_mempool_cbs ring_mp_callback = { 2819 .item_func_alloc = __vxge_hw_ring_mempool_item_alloc, 2820 }; 2821 2822 if ((vp == NULL) || (attr == NULL)) { 2823 status = VXGE_HW_FAIL; 2824 goto exit; 2825 } 2826 2827 hldev = vp->vpath->hldev; 2828 vp_id = vp->vpath->vp_id; 2829 2830 config = &hldev->config.vp_config[vp_id].ring; 2831 2832 ring_length = config->ring_blocks * 2833 vxge_hw_ring_rxds_per_block_get(config->buffer_mode); 2834 2835 ring = (struct __vxge_hw_ring *)__vxge_hw_channel_allocate(vp, 2836 VXGE_HW_CHANNEL_TYPE_RING, 2837 ring_length, 2838 attr->per_rxd_space, 2839 attr->userdata); 2840 if (ring == NULL) { 2841 status = VXGE_HW_ERR_OUT_OF_MEMORY; 2842 goto exit; 2843 } 2844 2845 vp->vpath->ringh = ring; 2846 ring->vp_id = vp_id; 2847 ring->vp_reg = vp->vpath->vp_reg; 2848 ring->common_reg = hldev->common_reg; 2849 ring->stats = &vp->vpath->sw_stats->ring_stats; 2850 ring->config = config; 2851 ring->callback = attr->callback; 2852 ring->rxd_init = attr->rxd_init; 2853 ring->rxd_term = attr->rxd_term; 2854 ring->buffer_mode = config->buffer_mode; 2855 ring->tim_rti_cfg1_saved = vp->vpath->tim_rti_cfg1_saved; 2856 ring->tim_rti_cfg3_saved = vp->vpath->tim_rti_cfg3_saved; 2857 ring->rxds_limit = config->rxds_limit; 2858 2859 ring->rxd_size = vxge_hw_ring_rxd_size_get(config->buffer_mode); 2860 ring->rxd_priv_size = 2861 sizeof(struct __vxge_hw_ring_rxd_priv) + attr->per_rxd_space; 2862 ring->per_rxd_space = attr->per_rxd_space; 2863 2864 ring->rxd_priv_size = 2865 ((ring->rxd_priv_size + VXGE_CACHE_LINE_SIZE - 1) / 2866 VXGE_CACHE_LINE_SIZE) * VXGE_CACHE_LINE_SIZE; 2867 2868 /* how many RxDs can fit into one block. Depends on configured 2869 * buffer_mode. */ 2870 ring->rxds_per_block = 2871 vxge_hw_ring_rxds_per_block_get(config->buffer_mode); 2872 2873 /* calculate actual RxD block private size */ 2874 ring->rxdblock_priv_size = ring->rxd_priv_size * ring->rxds_per_block; 2875 ring->mempool = __vxge_hw_mempool_create(hldev, 2876 VXGE_HW_BLOCK_SIZE, 2877 VXGE_HW_BLOCK_SIZE, 2878 ring->rxdblock_priv_size, 2879 ring->config->ring_blocks, 2880 ring->config->ring_blocks, 2881 &ring_mp_callback, 2882 ring); 2883 if (ring->mempool == NULL) { 2884 __vxge_hw_ring_delete(vp); 2885 return VXGE_HW_ERR_OUT_OF_MEMORY; 2886 } 2887 2888 status = __vxge_hw_channel_initialize(&ring->channel); 2889 if (status != VXGE_HW_OK) { 2890 __vxge_hw_ring_delete(vp); 2891 goto exit; 2892 } 2893 2894 /* Note: 2895 * Specifying rxd_init callback means two things: 2896 * 1) rxds need to be initialized by driver at channel-open time; 2897 * 2) rxds need to be posted at channel-open time 2898 * (that's what the initial_replenish() below does) 2899 * Currently we don't have a case when the 1) is done without the 2). 2900 */ 2901 if (ring->rxd_init) { 2902 status = vxge_hw_ring_replenish(ring); 2903 if (status != VXGE_HW_OK) { 2904 __vxge_hw_ring_delete(vp); 2905 goto exit; 2906 } 2907 } 2908 2909 /* initial replenish will increment the counter in its post() routine, 2910 * we have to reset it */ 2911 ring->stats->common_stats.usage_cnt = 0; 2912exit: 2913 return status; 2914} 2915 2916/* 2917 * vxge_hw_device_config_default_get - Initialize device config with defaults. 2918 * Initialize Titan device config with default values. 2919 */ 2920enum vxge_hw_status __devinit 2921vxge_hw_device_config_default_get(struct vxge_hw_device_config *device_config) 2922{ 2923 u32 i; 2924 2925 device_config->dma_blockpool_initial = 2926 VXGE_HW_INITIAL_DMA_BLOCK_POOL_SIZE; 2927 device_config->dma_blockpool_max = VXGE_HW_MAX_DMA_BLOCK_POOL_SIZE; 2928 device_config->intr_mode = VXGE_HW_INTR_MODE_DEF; 2929 device_config->rth_en = VXGE_HW_RTH_DEFAULT; 2930 device_config->rth_it_type = VXGE_HW_RTH_IT_TYPE_DEFAULT; 2931 device_config->device_poll_millis = VXGE_HW_DEF_DEVICE_POLL_MILLIS; 2932 device_config->rts_mac_en = VXGE_HW_RTS_MAC_DEFAULT; 2933 2934 for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) { 2935 device_config->vp_config[i].vp_id = i; 2936 2937 device_config->vp_config[i].min_bandwidth = 2938 VXGE_HW_VPATH_BANDWIDTH_DEFAULT; 2939 2940 device_config->vp_config[i].ring.enable = VXGE_HW_RING_DEFAULT; 2941 2942 device_config->vp_config[i].ring.ring_blocks = 2943 VXGE_HW_DEF_RING_BLOCKS; 2944 2945 device_config->vp_config[i].ring.buffer_mode = 2946 VXGE_HW_RING_RXD_BUFFER_MODE_DEFAULT; 2947 2948 device_config->vp_config[i].ring.scatter_mode = 2949 VXGE_HW_RING_SCATTER_MODE_USE_FLASH_DEFAULT; 2950 2951 device_config->vp_config[i].ring.rxds_limit = 2952 VXGE_HW_DEF_RING_RXDS_LIMIT; 2953 2954 device_config->vp_config[i].fifo.enable = VXGE_HW_FIFO_ENABLE; 2955 2956 device_config->vp_config[i].fifo.fifo_blocks = 2957 VXGE_HW_MIN_FIFO_BLOCKS; 2958 2959 device_config->vp_config[i].fifo.max_frags = 2960 VXGE_HW_MAX_FIFO_FRAGS; 2961 2962 device_config->vp_config[i].fifo.memblock_size = 2963 VXGE_HW_DEF_FIFO_MEMBLOCK_SIZE; 2964 2965 device_config->vp_config[i].fifo.alignment_size = 2966 VXGE_HW_DEF_FIFO_ALIGNMENT_SIZE; 2967 2968 device_config->vp_config[i].fifo.intr = 2969 VXGE_HW_FIFO_QUEUE_INTR_DEFAULT; 2970 2971 device_config->vp_config[i].fifo.no_snoop_bits = 2972 VXGE_HW_FIFO_NO_SNOOP_DEFAULT; 2973 device_config->vp_config[i].tti.intr_enable = 2974 VXGE_HW_TIM_INTR_DEFAULT; 2975 2976 device_config->vp_config[i].tti.btimer_val = 2977 VXGE_HW_USE_FLASH_DEFAULT; 2978 2979 device_config->vp_config[i].tti.timer_ac_en = 2980 VXGE_HW_USE_FLASH_DEFAULT; 2981 2982 device_config->vp_config[i].tti.timer_ci_en = 2983 VXGE_HW_USE_FLASH_DEFAULT; 2984 2985 device_config->vp_config[i].tti.timer_ri_en = 2986 VXGE_HW_USE_FLASH_DEFAULT; 2987 2988 device_config->vp_config[i].tti.rtimer_val = 2989 VXGE_HW_USE_FLASH_DEFAULT; 2990 2991 device_config->vp_config[i].tti.util_sel = 2992 VXGE_HW_USE_FLASH_DEFAULT; 2993 2994 device_config->vp_config[i].tti.ltimer_val = 2995 VXGE_HW_USE_FLASH_DEFAULT; 2996 2997 device_config->vp_config[i].tti.urange_a = 2998 VXGE_HW_USE_FLASH_DEFAULT; 2999 3000 device_config->vp_config[i].tti.uec_a = 3001 VXGE_HW_USE_FLASH_DEFAULT; 3002 3003 device_config->vp_config[i].tti.urange_b = 3004 VXGE_HW_USE_FLASH_DEFAULT; 3005 3006 device_config->vp_config[i].tti.uec_b = 3007 VXGE_HW_USE_FLASH_DEFAULT; 3008 3009 device_config->vp_config[i].tti.urange_c = 3010 VXGE_HW_USE_FLASH_DEFAULT; 3011 3012 device_config->vp_config[i].tti.uec_c = 3013 VXGE_HW_USE_FLASH_DEFAULT; 3014 3015 device_config->vp_config[i].tti.uec_d = 3016 VXGE_HW_USE_FLASH_DEFAULT; 3017 3018 device_config->vp_config[i].rti.intr_enable = 3019 VXGE_HW_TIM_INTR_DEFAULT; 3020 3021 device_config->vp_config[i].rti.btimer_val = 3022 VXGE_HW_USE_FLASH_DEFAULT; 3023 3024 device_config->vp_config[i].rti.timer_ac_en = 3025 VXGE_HW_USE_FLASH_DEFAULT; 3026 3027 device_config->vp_config[i].rti.timer_ci_en = 3028 VXGE_HW_USE_FLASH_DEFAULT; 3029 3030 device_config->vp_config[i].rti.timer_ri_en = 3031 VXGE_HW_USE_FLASH_DEFAULT; 3032 3033 device_config->vp_config[i].rti.rtimer_val = 3034 VXGE_HW_USE_FLASH_DEFAULT; 3035 3036 device_config->vp_config[i].rti.util_sel = 3037 VXGE_HW_USE_FLASH_DEFAULT; 3038 3039 device_config->vp_config[i].rti.ltimer_val = 3040 VXGE_HW_USE_FLASH_DEFAULT; 3041 3042 device_config->vp_config[i].rti.urange_a = 3043 VXGE_HW_USE_FLASH_DEFAULT; 3044 3045 device_config->vp_config[i].rti.uec_a = 3046 VXGE_HW_USE_FLASH_DEFAULT; 3047 3048 device_config->vp_config[i].rti.urange_b = 3049 VXGE_HW_USE_FLASH_DEFAULT; 3050 3051 device_config->vp_config[i].rti.uec_b = 3052 VXGE_HW_USE_FLASH_DEFAULT; 3053 3054 device_config->vp_config[i].rti.urange_c = 3055 VXGE_HW_USE_FLASH_DEFAULT; 3056 3057 device_config->vp_config[i].rti.uec_c = 3058 VXGE_HW_USE_FLASH_DEFAULT; 3059 3060 device_config->vp_config[i].rti.uec_d = 3061 VXGE_HW_USE_FLASH_DEFAULT; 3062 3063 device_config->vp_config[i].mtu = 3064 VXGE_HW_VPATH_USE_FLASH_DEFAULT_INITIAL_MTU; 3065 3066 device_config->vp_config[i].rpa_strip_vlan_tag = 3067 VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_USE_FLASH_DEFAULT; 3068 } 3069 3070 return VXGE_HW_OK; 3071} 3072 3073/* 3074 * __vxge_hw_vpath_swapper_set - Set the swapper bits for the vpath. 3075 * Set the swapper bits appropriately for the vpath. 3076 */ 3077static enum vxge_hw_status 3078__vxge_hw_vpath_swapper_set(struct vxge_hw_vpath_reg __iomem *vpath_reg) 3079{ 3080#ifndef __BIG_ENDIAN 3081 u64 val64; 3082 3083 val64 = readq(&vpath_reg->vpath_general_cfg1); 3084 wmb(); 3085 val64 |= VXGE_HW_VPATH_GENERAL_CFG1_CTL_BYTE_SWAPEN; 3086 writeq(val64, &vpath_reg->vpath_general_cfg1); 3087 wmb(); 3088#endif 3089 return VXGE_HW_OK; 3090} 3091 3092/* 3093 * __vxge_hw_kdfc_swapper_set - Set the swapper bits for the kdfc. 3094 * Set the swapper bits appropriately for the vpath. 3095 */ 3096static enum vxge_hw_status 3097__vxge_hw_kdfc_swapper_set(struct vxge_hw_legacy_reg __iomem *legacy_reg, 3098 struct vxge_hw_vpath_reg __iomem *vpath_reg) 3099{ 3100 u64 val64; 3101 3102 val64 = readq(&legacy_reg->pifm_wr_swap_en); 3103 3104 if (val64 == VXGE_HW_SWAPPER_WRITE_BYTE_SWAP_ENABLE) { 3105 val64 = readq(&vpath_reg->kdfcctl_cfg0); 3106 wmb(); 3107 3108 val64 |= VXGE_HW_KDFCCTL_CFG0_BYTE_SWAPEN_FIFO0 | 3109 VXGE_HW_KDFCCTL_CFG0_BYTE_SWAPEN_FIFO1 | 3110 VXGE_HW_KDFCCTL_CFG0_BYTE_SWAPEN_FIFO2; 3111 3112 writeq(val64, &vpath_reg->kdfcctl_cfg0); 3113 wmb(); 3114 } 3115 3116 return VXGE_HW_OK; 3117} 3118 3119/* 3120 * vxge_hw_mgmt_reg_read - Read Titan register. 3121 */ 3122enum vxge_hw_status 3123vxge_hw_mgmt_reg_read(struct __vxge_hw_device *hldev, 3124 enum vxge_hw_mgmt_reg_type type, 3125 u32 index, u32 offset, u64 *value) 3126{ 3127 enum vxge_hw_status status = VXGE_HW_OK; 3128 3129 if ((hldev == NULL) || (hldev->magic != VXGE_HW_DEVICE_MAGIC)) { 3130 status = VXGE_HW_ERR_INVALID_DEVICE; 3131 goto exit; 3132 } 3133 3134 switch (type) { 3135 case vxge_hw_mgmt_reg_type_legacy: 3136 if (offset > sizeof(struct vxge_hw_legacy_reg) - 8) { 3137 status = VXGE_HW_ERR_INVALID_OFFSET; 3138 break; 3139 } 3140 *value = readq((void __iomem *)hldev->legacy_reg + offset); 3141 break; 3142 case vxge_hw_mgmt_reg_type_toc: 3143 if (offset > sizeof(struct vxge_hw_toc_reg) - 8) { 3144 status = VXGE_HW_ERR_INVALID_OFFSET; 3145 break; 3146 } 3147 *value = readq((void __iomem *)hldev->toc_reg + offset); 3148 break; 3149 case vxge_hw_mgmt_reg_type_common: 3150 if (offset > sizeof(struct vxge_hw_common_reg) - 8) { 3151 status = VXGE_HW_ERR_INVALID_OFFSET; 3152 break; 3153 } 3154 *value = readq((void __iomem *)hldev->common_reg + offset); 3155 break; 3156 case vxge_hw_mgmt_reg_type_mrpcim: 3157 if (!(hldev->access_rights & 3158 VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM)) { 3159 status = VXGE_HW_ERR_PRIVILAGED_OPEARATION; 3160 break; 3161 } 3162 if (offset > sizeof(struct vxge_hw_mrpcim_reg) - 8) { 3163 status = VXGE_HW_ERR_INVALID_OFFSET; 3164 break; 3165 } 3166 *value = readq((void __iomem *)hldev->mrpcim_reg + offset); 3167 break; 3168 case vxge_hw_mgmt_reg_type_srpcim: 3169 if (!(hldev->access_rights & 3170 VXGE_HW_DEVICE_ACCESS_RIGHT_SRPCIM)) { 3171 status = VXGE_HW_ERR_PRIVILAGED_OPEARATION; 3172 break; 3173 } 3174 if (index > VXGE_HW_TITAN_SRPCIM_REG_SPACES - 1) { 3175 status = VXGE_HW_ERR_INVALID_INDEX; 3176 break; 3177 } 3178 if (offset > sizeof(struct vxge_hw_srpcim_reg) - 8) { 3179 status = VXGE_HW_ERR_INVALID_OFFSET; 3180 break; 3181 } 3182 *value = readq((void __iomem *)hldev->srpcim_reg[index] + 3183 offset); 3184 break; 3185 case vxge_hw_mgmt_reg_type_vpmgmt: 3186 if ((index > VXGE_HW_TITAN_VPMGMT_REG_SPACES - 1) || 3187 (!(hldev->vpath_assignments & vxge_mBIT(index)))) { 3188 status = VXGE_HW_ERR_INVALID_INDEX; 3189 break; 3190 } 3191 if (offset > sizeof(struct vxge_hw_vpmgmt_reg) - 8) { 3192 status = VXGE_HW_ERR_INVALID_OFFSET; 3193 break; 3194 } 3195 *value = readq((void __iomem *)hldev->vpmgmt_reg[index] + 3196 offset); 3197 break; 3198 case vxge_hw_mgmt_reg_type_vpath: 3199 if ((index > VXGE_HW_TITAN_VPATH_REG_SPACES - 1) || 3200 (!(hldev->vpath_assignments & vxge_mBIT(index)))) { 3201 status = VXGE_HW_ERR_INVALID_INDEX; 3202 break; 3203 } 3204 if (index > VXGE_HW_TITAN_VPATH_REG_SPACES - 1) { 3205 status = VXGE_HW_ERR_INVALID_INDEX; 3206 break; 3207 } 3208 if (offset > sizeof(struct vxge_hw_vpath_reg) - 8) { 3209 status = VXGE_HW_ERR_INVALID_OFFSET; 3210 break; 3211 } 3212 *value = readq((void __iomem *)hldev->vpath_reg[index] + 3213 offset); 3214 break; 3215 default: 3216 status = VXGE_HW_ERR_INVALID_TYPE; 3217 break; 3218 } 3219 3220exit: 3221 return status; 3222} 3223 3224/* 3225 * vxge_hw_vpath_strip_fcs_check - Check for FCS strip. 3226 */ 3227enum vxge_hw_status 3228vxge_hw_vpath_strip_fcs_check(struct __vxge_hw_device *hldev, u64 vpath_mask) 3229{ 3230 struct vxge_hw_vpmgmt_reg __iomem *vpmgmt_reg; 3231 enum vxge_hw_status status = VXGE_HW_OK; 3232 int i = 0, j = 0; 3233 3234 for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) { 3235 if (!((vpath_mask) & vxge_mBIT(i))) 3236 continue; 3237 vpmgmt_reg = hldev->vpmgmt_reg[i]; 3238 for (j = 0; j < VXGE_HW_MAC_MAX_MAC_PORT_ID; j++) { 3239 if (readq(&vpmgmt_reg->rxmac_cfg0_port_vpmgmt_clone[j]) 3240 & VXGE_HW_RXMAC_CFG0_PORT_VPMGMT_CLONE_STRIP_FCS) 3241 return VXGE_HW_FAIL; 3242 } 3243 } 3244 return status; 3245} 3246/* 3247 * vxge_hw_mgmt_reg_Write - Write Titan register. 3248 */ 3249enum vxge_hw_status 3250vxge_hw_mgmt_reg_write(struct __vxge_hw_device *hldev, 3251 enum vxge_hw_mgmt_reg_type type, 3252 u32 index, u32 offset, u64 value) 3253{ 3254 enum vxge_hw_status status = VXGE_HW_OK; 3255 3256 if ((hldev == NULL) || (hldev->magic != VXGE_HW_DEVICE_MAGIC)) { 3257 status = VXGE_HW_ERR_INVALID_DEVICE; 3258 goto exit; 3259 } 3260 3261 switch (type) { 3262 case vxge_hw_mgmt_reg_type_legacy: 3263 if (offset > sizeof(struct vxge_hw_legacy_reg) - 8) { 3264 status = VXGE_HW_ERR_INVALID_OFFSET; 3265 break; 3266 } 3267 writeq(value, (void __iomem *)hldev->legacy_reg + offset); 3268 break; 3269 case vxge_hw_mgmt_reg_type_toc: 3270 if (offset > sizeof(struct vxge_hw_toc_reg) - 8) { 3271 status = VXGE_HW_ERR_INVALID_OFFSET; 3272 break; 3273 } 3274 writeq(value, (void __iomem *)hldev->toc_reg + offset); 3275 break; 3276 case vxge_hw_mgmt_reg_type_common: 3277 if (offset > sizeof(struct vxge_hw_common_reg) - 8) { 3278 status = VXGE_HW_ERR_INVALID_OFFSET; 3279 break; 3280 } 3281 writeq(value, (void __iomem *)hldev->common_reg + offset); 3282 break; 3283 case vxge_hw_mgmt_reg_type_mrpcim: 3284 if (!(hldev->access_rights & 3285 VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM)) { 3286 status = VXGE_HW_ERR_PRIVILAGED_OPEARATION; 3287 break; 3288 } 3289 if (offset > sizeof(struct vxge_hw_mrpcim_reg) - 8) { 3290 status = VXGE_HW_ERR_INVALID_OFFSET; 3291 break; 3292 } 3293 writeq(value, (void __iomem *)hldev->mrpcim_reg + offset); 3294 break; 3295 case vxge_hw_mgmt_reg_type_srpcim: 3296 if (!(hldev->access_rights & 3297 VXGE_HW_DEVICE_ACCESS_RIGHT_SRPCIM)) { 3298 status = VXGE_HW_ERR_PRIVILAGED_OPEARATION; 3299 break; 3300 } 3301 if (index > VXGE_HW_TITAN_SRPCIM_REG_SPACES - 1) { 3302 status = VXGE_HW_ERR_INVALID_INDEX; 3303 break; 3304 } 3305 if (offset > sizeof(struct vxge_hw_srpcim_reg) - 8) { 3306 status = VXGE_HW_ERR_INVALID_OFFSET; 3307 break; 3308 } 3309 writeq(value, (void __iomem *)hldev->srpcim_reg[index] + 3310 offset); 3311 3312 break; 3313 case vxge_hw_mgmt_reg_type_vpmgmt: 3314 if ((index > VXGE_HW_TITAN_VPMGMT_REG_SPACES - 1) || 3315 (!(hldev->vpath_assignments & vxge_mBIT(index)))) { 3316 status = VXGE_HW_ERR_INVALID_INDEX; 3317 break; 3318 } 3319 if (offset > sizeof(struct vxge_hw_vpmgmt_reg) - 8) { 3320 status = VXGE_HW_ERR_INVALID_OFFSET; 3321 break; 3322 } 3323 writeq(value, (void __iomem *)hldev->vpmgmt_reg[index] + 3324 offset); 3325 break; 3326 case vxge_hw_mgmt_reg_type_vpath: 3327 if ((index > VXGE_HW_TITAN_VPATH_REG_SPACES-1) || 3328 (!(hldev->vpath_assignments & vxge_mBIT(index)))) { 3329 status = VXGE_HW_ERR_INVALID_INDEX; 3330 break; 3331 } 3332 if (offset > sizeof(struct vxge_hw_vpath_reg) - 8) { 3333 status = VXGE_HW_ERR_INVALID_OFFSET; 3334 break; 3335 } 3336 writeq(value, (void __iomem *)hldev->vpath_reg[index] + 3337 offset); 3338 break; 3339 default: 3340 status = VXGE_HW_ERR_INVALID_TYPE; 3341 break; 3342 } 3343exit: 3344 return status; 3345} 3346 3347/* 3348 * __vxge_hw_fifo_abort - Returns the TxD 3349 * This function terminates the TxDs of fifo 3350 */ 3351static enum vxge_hw_status __vxge_hw_fifo_abort(struct __vxge_hw_fifo *fifo) 3352{ 3353 void *txdlh; 3354 3355 for (;;) { 3356 vxge_hw_channel_dtr_try_complete(&fifo->channel, &txdlh); 3357 3358 if (txdlh == NULL) 3359 break; 3360 3361 vxge_hw_channel_dtr_complete(&fifo->channel); 3362 3363 if (fifo->txdl_term) { 3364 fifo->txdl_term(txdlh, 3365 VXGE_HW_TXDL_STATE_POSTED, 3366 fifo->channel.userdata); 3367 } 3368 3369 vxge_hw_channel_dtr_free(&fifo->channel, txdlh); 3370 } 3371 3372 return VXGE_HW_OK; 3373} 3374 3375/* 3376 * __vxge_hw_fifo_reset - Resets the fifo 3377 * This function resets the fifo during vpath reset operation 3378 */ 3379static enum vxge_hw_status __vxge_hw_fifo_reset(struct __vxge_hw_fifo *fifo) 3380{ 3381 enum vxge_hw_status status = VXGE_HW_OK; 3382 3383 __vxge_hw_fifo_abort(fifo); 3384 status = __vxge_hw_channel_reset(&fifo->channel); 3385 3386 return status; 3387} 3388 3389/* 3390 * __vxge_hw_fifo_delete - Removes the FIFO 3391 * This function freeup the memory pool and removes the FIFO 3392 */ 3393static enum vxge_hw_status 3394__vxge_hw_fifo_delete(struct __vxge_hw_vpath_handle *vp) 3395{ 3396 struct __vxge_hw_fifo *fifo = vp->vpath->fifoh; 3397 3398 __vxge_hw_fifo_abort(fifo); 3399 3400 if (fifo->mempool) 3401 __vxge_hw_mempool_destroy(fifo->mempool); 3402 3403 vp->vpath->fifoh = NULL; 3404 3405 __vxge_hw_channel_free(&fifo->channel); 3406 3407 return VXGE_HW_OK; 3408} 3409 3410/* 3411 * __vxge_hw_fifo_mempool_item_alloc - Allocate List blocks for TxD 3412 * list callback 3413 * This function is callback passed to __vxge_hw_mempool_create to create memory 3414 * pool for TxD list 3415 */ 3416static void 3417__vxge_hw_fifo_mempool_item_alloc( 3418 struct vxge_hw_mempool *mempoolh, 3419 u32 memblock_index, struct vxge_hw_mempool_dma *dma_object, 3420 u32 index, u32 is_last) 3421{ 3422 u32 memblock_item_idx; 3423 struct __vxge_hw_fifo_txdl_priv *txdl_priv; 3424 struct vxge_hw_fifo_txd *txdp = 3425 (struct vxge_hw_fifo_txd *)mempoolh->items_arr[index]; 3426 struct __vxge_hw_fifo *fifo = 3427 (struct __vxge_hw_fifo *)mempoolh->userdata; 3428 void *memblock = mempoolh->memblocks_arr[memblock_index]; 3429 3430 vxge_assert(txdp); 3431 3432 txdp->host_control = (u64) (size_t) 3433 __vxge_hw_mempool_item_priv(mempoolh, memblock_index, txdp, 3434 &memblock_item_idx); 3435 3436 txdl_priv = __vxge_hw_fifo_txdl_priv(fifo, txdp); 3437 3438 vxge_assert(txdl_priv); 3439 3440 fifo->channel.reserve_arr[fifo->channel.reserve_ptr - 1 - index] = txdp; 3441 3442 /* pre-format HW's TxDL's private */ 3443 txdl_priv->dma_offset = (char *)txdp - (char *)memblock; 3444 txdl_priv->dma_addr = dma_object->addr + txdl_priv->dma_offset; 3445 txdl_priv->dma_handle = dma_object->handle; 3446 txdl_priv->memblock = memblock; 3447 txdl_priv->first_txdp = txdp; 3448 txdl_priv->next_txdl_priv = NULL; 3449 txdl_priv->alloc_frags = 0; 3450} 3451 3452/* 3453 * __vxge_hw_fifo_create - Create a FIFO 3454 * This function creates FIFO and initializes it. 3455 */ 3456static enum vxge_hw_status 3457__vxge_hw_fifo_create(struct __vxge_hw_vpath_handle *vp, 3458 struct vxge_hw_fifo_attr *attr) 3459{ 3460 enum vxge_hw_status status = VXGE_HW_OK; 3461 struct __vxge_hw_fifo *fifo; 3462 struct vxge_hw_fifo_config *config; 3463 u32 txdl_size, txdl_per_memblock; 3464 struct vxge_hw_mempool_cbs fifo_mp_callback; 3465 struct __vxge_hw_virtualpath *vpath; 3466 3467 if ((vp == NULL) || (attr == NULL)) { 3468 status = VXGE_HW_ERR_INVALID_HANDLE; 3469 goto exit; 3470 } 3471 vpath = vp->vpath; 3472 config = &vpath->hldev->config.vp_config[vpath->vp_id].fifo; 3473 3474 txdl_size = config->max_frags * sizeof(struct vxge_hw_fifo_txd); 3475 3476 txdl_per_memblock = config->memblock_size / txdl_size; 3477 3478 fifo = (struct __vxge_hw_fifo *)__vxge_hw_channel_allocate(vp, 3479 VXGE_HW_CHANNEL_TYPE_FIFO, 3480 config->fifo_blocks * txdl_per_memblock, 3481 attr->per_txdl_space, attr->userdata); 3482 3483 if (fifo == NULL) { 3484 status = VXGE_HW_ERR_OUT_OF_MEMORY; 3485 goto exit; 3486 } 3487 3488 vpath->fifoh = fifo; 3489 fifo->nofl_db = vpath->nofl_db; 3490 3491 fifo->vp_id = vpath->vp_id; 3492 fifo->vp_reg = vpath->vp_reg; 3493 fifo->stats = &vpath->sw_stats->fifo_stats; 3494 3495 fifo->config = config; 3496 3497 /* apply "interrupts per txdl" attribute */ 3498 fifo->interrupt_type = VXGE_HW_FIFO_TXD_INT_TYPE_UTILZ; 3499 fifo->tim_tti_cfg1_saved = vpath->tim_tti_cfg1_saved; 3500 fifo->tim_tti_cfg3_saved = vpath->tim_tti_cfg3_saved; 3501 3502 if (fifo->config->intr) 3503 fifo->interrupt_type = VXGE_HW_FIFO_TXD_INT_TYPE_PER_LIST; 3504 3505 fifo->no_snoop_bits = config->no_snoop_bits; 3506 3507 /* 3508 * FIFO memory management strategy: 3509 * 3510 * TxDL split into three independent parts: 3511 * - set of TxD's 3512 * - TxD HW private part 3513 * - driver private part 3514 * 3515 * Adaptative memory allocation used. i.e. Memory allocated on 3516 * demand with the size which will fit into one memory block. 3517 * One memory block may contain more than one TxDL. 3518 * 3519 * During "reserve" operations more memory can be allocated on demand 3520 * for example due to FIFO full condition. 3521 * 3522 * Pool of memory memblocks never shrinks except in __vxge_hw_fifo_close 3523 * routine which will essentially stop the channel and free resources. 3524 */ 3525 3526 /* TxDL common private size == TxDL private + driver private */ 3527 fifo->priv_size = 3528 sizeof(struct __vxge_hw_fifo_txdl_priv) + attr->per_txdl_space; 3529 fifo->priv_size = ((fifo->priv_size + VXGE_CACHE_LINE_SIZE - 1) / 3530 VXGE_CACHE_LINE_SIZE) * VXGE_CACHE_LINE_SIZE; 3531 3532 fifo->per_txdl_space = attr->per_txdl_space; 3533 3534 /* recompute txdl size to be cacheline aligned */ 3535 fifo->txdl_size = txdl_size; 3536 fifo->txdl_per_memblock = txdl_per_memblock; 3537 3538 fifo->txdl_term = attr->txdl_term; 3539 fifo->callback = attr->callback; 3540 3541 if (fifo->txdl_per_memblock == 0) { 3542 __vxge_hw_fifo_delete(vp); 3543 status = VXGE_HW_ERR_INVALID_BLOCK_SIZE; 3544 goto exit; 3545 } 3546 3547 fifo_mp_callback.item_func_alloc = __vxge_hw_fifo_mempool_item_alloc; 3548 3549 fifo->mempool = 3550 __vxge_hw_mempool_create(vpath->hldev, 3551 fifo->config->memblock_size, 3552 fifo->txdl_size, 3553 fifo->priv_size, 3554 (fifo->config->fifo_blocks * fifo->txdl_per_memblock), 3555 (fifo->config->fifo_blocks * fifo->txdl_per_memblock), 3556 &fifo_mp_callback, 3557 fifo); 3558 3559 if (fifo->mempool == NULL) { 3560 __vxge_hw_fifo_delete(vp); 3561 status = VXGE_HW_ERR_OUT_OF_MEMORY; 3562 goto exit; 3563 } 3564 3565 status = __vxge_hw_channel_initialize(&fifo->channel); 3566 if (status != VXGE_HW_OK) { 3567 __vxge_hw_fifo_delete(vp); 3568 goto exit; 3569 } 3570 3571 vxge_assert(fifo->channel.reserve_ptr); 3572exit: 3573 return status; 3574} 3575 3576/* 3577 * __vxge_hw_vpath_pci_read - Read the content of given address 3578 * in pci config space. 3579 * Read from the vpath pci config space. 3580 */ 3581static enum vxge_hw_status 3582__vxge_hw_vpath_pci_read(struct __vxge_hw_virtualpath *vpath, 3583 u32 phy_func_0, u32 offset, u32 *val) 3584{ 3585 u64 val64; 3586 enum vxge_hw_status status = VXGE_HW_OK; 3587 struct vxge_hw_vpath_reg __iomem *vp_reg = vpath->vp_reg; 3588 3589 val64 = VXGE_HW_PCI_CONFIG_ACCESS_CFG1_ADDRESS(offset); 3590 3591 if (phy_func_0) 3592 val64 |= VXGE_HW_PCI_CONFIG_ACCESS_CFG1_SEL_FUNC0; 3593 3594 writeq(val64, &vp_reg->pci_config_access_cfg1); 3595 wmb(); 3596 writeq(VXGE_HW_PCI_CONFIG_ACCESS_CFG2_REQ, 3597 &vp_reg->pci_config_access_cfg2); 3598 wmb(); 3599 3600 status = __vxge_hw_device_register_poll( 3601 &vp_reg->pci_config_access_cfg2, 3602 VXGE_HW_INTR_MASK_ALL, VXGE_HW_DEF_DEVICE_POLL_MILLIS); 3603 3604 if (status != VXGE_HW_OK) 3605 goto exit; 3606 3607 val64 = readq(&vp_reg->pci_config_access_status); 3608 3609 if (val64 & VXGE_HW_PCI_CONFIG_ACCESS_STATUS_ACCESS_ERR) { 3610 status = VXGE_HW_FAIL; 3611 *val = 0; 3612 } else 3613 *val = (u32)vxge_bVALn(val64, 32, 32); 3614exit: 3615 return status; 3616} 3617 3618/** 3619 * vxge_hw_device_flick_link_led - Flick (blink) link LED. 3620 * @hldev: HW device. 3621 * @on_off: TRUE if flickering to be on, FALSE to be off 3622 * 3623 * Flicker the link LED. 3624 */ 3625enum vxge_hw_status 3626vxge_hw_device_flick_link_led(struct __vxge_hw_device *hldev, u64 on_off) 3627{ 3628 struct __vxge_hw_virtualpath *vpath; 3629 u64 data0, data1 = 0, steer_ctrl = 0; 3630 enum vxge_hw_status status; 3631 3632 if (hldev == NULL) { 3633 status = VXGE_HW_ERR_INVALID_DEVICE; 3634 goto exit; 3635 } 3636 3637 vpath = &hldev->virtual_paths[hldev->first_vp_id]; 3638 3639 data0 = on_off; 3640 status = vxge_hw_vpath_fw_api(vpath, 3641 VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LED_CONTROL, 3642 VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO, 3643 0, &data0, &data1, &steer_ctrl); 3644exit: 3645 return status; 3646} 3647 3648/* 3649 * __vxge_hw_vpath_rts_table_get - Get the entries from RTS access tables 3650 */ 3651enum vxge_hw_status 3652__vxge_hw_vpath_rts_table_get(struct __vxge_hw_vpath_handle *vp, 3653 u32 action, u32 rts_table, u32 offset, 3654 u64 *data0, u64 *data1) 3655{ 3656 enum vxge_hw_status status; 3657 u64 steer_ctrl = 0; 3658 3659 if (vp == NULL) { 3660 status = VXGE_HW_ERR_INVALID_HANDLE; 3661 goto exit; 3662 } 3663 3664 if ((rts_table == 3665 VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_SOLO_IT) || 3666 (rts_table == 3667 VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT) || 3668 (rts_table == 3669 VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MASK) || 3670 (rts_table == 3671 VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_KEY)) { 3672 steer_ctrl = VXGE_HW_RTS_ACCESS_STEER_CTRL_TABLE_SEL; 3673 } 3674 3675 status = vxge_hw_vpath_fw_api(vp->vpath, action, rts_table, offset, 3676 data0, data1, &steer_ctrl); 3677 if (status != VXGE_HW_OK) 3678 goto exit; 3679 3680 if ((rts_table != VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA) && 3681 (rts_table != 3682 VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT)) 3683 *data1 = 0; 3684exit: 3685 return status; 3686} 3687 3688/* 3689 * __vxge_hw_vpath_rts_table_set - Set the entries of RTS access tables 3690 */ 3691enum vxge_hw_status 3692__vxge_hw_vpath_rts_table_set(struct __vxge_hw_vpath_handle *vp, u32 action, 3693 u32 rts_table, u32 offset, u64 steer_data0, 3694 u64 steer_data1) 3695{ 3696 u64 data0, data1 = 0, steer_ctrl = 0; 3697 enum vxge_hw_status status; 3698 3699 if (vp == NULL) { 3700 status = VXGE_HW_ERR_INVALID_HANDLE; 3701 goto exit; 3702 } 3703 3704 data0 = steer_data0; 3705 3706 if ((rts_table == VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA) || 3707 (rts_table == 3708 VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT)) 3709 data1 = steer_data1; 3710 3711 status = vxge_hw_vpath_fw_api(vp->vpath, action, rts_table, offset, 3712 &data0, &data1, &steer_ctrl); 3713exit: 3714 return status; 3715} 3716 3717/* 3718 * vxge_hw_vpath_rts_rth_set - Set/configure RTS hashing. 3719 */ 3720enum vxge_hw_status vxge_hw_vpath_rts_rth_set( 3721 struct __vxge_hw_vpath_handle *vp, 3722 enum vxge_hw_rth_algoritms algorithm, 3723 struct vxge_hw_rth_hash_types *hash_type, 3724 u16 bucket_size) 3725{ 3726 u64 data0, data1; 3727 enum vxge_hw_status status = VXGE_HW_OK; 3728 3729 if (vp == NULL) { 3730 status = VXGE_HW_ERR_INVALID_HANDLE; 3731 goto exit; 3732 } 3733 3734 status = __vxge_hw_vpath_rts_table_get(vp, 3735 VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_ENTRY, 3736 VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_GEN_CFG, 3737 0, &data0, &data1); 3738 if (status != VXGE_HW_OK) 3739 goto exit; 3740 3741 data0 &= ~(VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_BUCKET_SIZE(0xf) | 3742 VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_ALG_SEL(0x3)); 3743 3744 data0 |= VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_EN | 3745 VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_BUCKET_SIZE(bucket_size) | 3746 VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_ALG_SEL(algorithm); 3747 3748 if (hash_type->hash_type_tcpipv4_en) 3749 data0 |= VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_TCP_IPV4_EN; 3750 3751 if (hash_type->hash_type_ipv4_en) 3752 data0 |= VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_IPV4_EN; 3753 3754 if (hash_type->hash_type_tcpipv6_en) 3755 data0 |= VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_TCP_IPV6_EN; 3756 3757 if (hash_type->hash_type_ipv6_en) 3758 data0 |= VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_IPV6_EN; 3759 3760 if (hash_type->hash_type_tcpipv6ex_en) 3761 data0 |= 3762 VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_TCP_IPV6_EX_EN; 3763 3764 if (hash_type->hash_type_ipv6ex_en) 3765 data0 |= VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_IPV6_EX_EN; 3766 3767 if (VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_GEN_ACTIVE_TABLE(data0)) 3768 data0 &= ~VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_ACTIVE_TABLE; 3769 else 3770 data0 |= VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_ACTIVE_TABLE; 3771 3772 status = __vxge_hw_vpath_rts_table_set(vp, 3773 VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_WRITE_ENTRY, 3774 VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_GEN_CFG, 3775 0, data0, 0); 3776exit: 3777 return status; 3778} 3779 3780static void 3781vxge_hw_rts_rth_data0_data1_get(u32 j, u64 *data0, u64 *data1, 3782 u16 flag, u8 *itable) 3783{ 3784 switch (flag) { 3785 case 1: 3786 *data0 = VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM0_BUCKET_NUM(j)| 3787 VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM0_ENTRY_EN | 3788 VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM0_BUCKET_DATA( 3789 itable[j]); 3790 case 2: 3791 *data0 |= 3792 VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM1_BUCKET_NUM(j)| 3793 VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM1_ENTRY_EN | 3794 VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM1_BUCKET_DATA( 3795 itable[j]); 3796 case 3: 3797 *data1 = VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM0_BUCKET_NUM(j)| 3798 VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM0_ENTRY_EN | 3799 VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM0_BUCKET_DATA( 3800 itable[j]); 3801 case 4: 3802 *data1 |= 3803 VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM1_BUCKET_NUM(j)| 3804 VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM1_ENTRY_EN | 3805 VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM1_BUCKET_DATA( 3806 itable[j]); 3807 default: 3808 return; 3809 } 3810} 3811/* 3812 * vxge_hw_vpath_rts_rth_itable_set - Set/configure indirection table (IT). 3813 */ 3814enum vxge_hw_status vxge_hw_vpath_rts_rth_itable_set( 3815 struct __vxge_hw_vpath_handle **vpath_handles, 3816 u32 vpath_count, 3817 u8 *mtable, 3818 u8 *itable, 3819 u32 itable_size) 3820{ 3821 u32 i, j, action, rts_table; 3822 u64 data0; 3823 u64 data1; 3824 u32 max_entries; 3825 enum vxge_hw_status status = VXGE_HW_OK; 3826 struct __vxge_hw_vpath_handle *vp = vpath_handles[0]; 3827 3828 if (vp == NULL) { 3829 status = VXGE_HW_ERR_INVALID_HANDLE; 3830 goto exit; 3831 } 3832 3833 max_entries = (((u32)1) << itable_size); 3834 3835 if (vp->vpath->hldev->config.rth_it_type 3836 == VXGE_HW_RTH_IT_TYPE_SOLO_IT) { 3837 action = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_WRITE_ENTRY; 3838 rts_table = 3839 VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_SOLO_IT; 3840 3841 for (j = 0; j < max_entries; j++) { 3842 3843 data1 = 0; 3844 3845 data0 = 3846 VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_SOLO_IT_BUCKET_DATA( 3847 itable[j]); 3848 3849 status = __vxge_hw_vpath_rts_table_set(vpath_handles[0], 3850 action, rts_table, j, data0, data1); 3851 3852 if (status != VXGE_HW_OK) 3853 goto exit; 3854 } 3855 3856 for (j = 0; j < max_entries; j++) { 3857 3858 data1 = 0; 3859 3860 data0 = 3861 VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_SOLO_IT_ENTRY_EN | 3862 VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_SOLO_IT_BUCKET_DATA( 3863 itable[j]); 3864 3865 status = __vxge_hw_vpath_rts_table_set( 3866 vpath_handles[mtable[itable[j]]], action, 3867 rts_table, j, data0, data1); 3868 3869 if (status != VXGE_HW_OK) 3870 goto exit; 3871 } 3872 } else { 3873 action = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_WRITE_ENTRY; 3874 rts_table = 3875 VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT; 3876 for (i = 0; i < vpath_count; i++) { 3877 3878 for (j = 0; j < max_entries;) { 3879 3880 data0 = 0; 3881 data1 = 0; 3882 3883 while (j < max_entries) { 3884 if (mtable[itable[j]] != i) { 3885 j++; 3886 continue; 3887 } 3888 vxge_hw_rts_rth_data0_data1_get(j, 3889 &data0, &data1, 1, itable); 3890 j++; 3891 break; 3892 } 3893 3894 while (j < max_entries) { 3895 if (mtable[itable[j]] != i) { 3896 j++; 3897 continue; 3898 } 3899 vxge_hw_rts_rth_data0_data1_get(j, 3900 &data0, &data1, 2, itable); 3901 j++; 3902 break; 3903 } 3904 3905 while (j < max_entries) { 3906 if (mtable[itable[j]] != i) { 3907 j++; 3908 continue; 3909 } 3910 vxge_hw_rts_rth_data0_data1_get(j, 3911 &data0, &data1, 3, itable); 3912 j++; 3913 break; 3914 } 3915 3916 while (j < max_entries) { 3917 if (mtable[itable[j]] != i) { 3918 j++; 3919 continue; 3920 } 3921 vxge_hw_rts_rth_data0_data1_get(j, 3922 &data0, &data1, 4, itable); 3923 j++; 3924 break; 3925 } 3926 3927 if (data0 != 0) { 3928 status = __vxge_hw_vpath_rts_table_set( 3929 vpath_handles[i], 3930 action, rts_table, 3931 0, data0, data1); 3932 3933 if (status != VXGE_HW_OK) 3934 goto exit; 3935 } 3936 } 3937 } 3938 } 3939exit: 3940 return status; 3941} 3942 3943/** 3944 * vxge_hw_vpath_check_leak - Check for memory leak 3945 * @ringh: Handle to the ring object used for receive 3946 * 3947 * If PRC_RXD_DOORBELL_VPn.NEW_QW_CNT is larger or equal to 3948 * PRC_CFG6_VPn.RXD_SPAT then a leak has occurred. 3949 * Returns: VXGE_HW_FAIL, if leak has occurred. 3950 * 3951 */ 3952enum vxge_hw_status 3953vxge_hw_vpath_check_leak(struct __vxge_hw_ring *ring) 3954{ 3955 enum vxge_hw_status status = VXGE_HW_OK; 3956 u64 rxd_new_count, rxd_spat; 3957 3958 if (ring == NULL) 3959 return status; 3960 3961 rxd_new_count = readl(&ring->vp_reg->prc_rxd_doorbell); 3962 rxd_spat = readq(&ring->vp_reg->prc_cfg6); 3963 rxd_spat = VXGE_HW_PRC_CFG6_RXD_SPAT(rxd_spat); 3964 3965 if (rxd_new_count >= rxd_spat) 3966 status = VXGE_HW_FAIL; 3967 3968 return status; 3969} 3970 3971/* 3972 * __vxge_hw_vpath_mgmt_read 3973 * This routine reads the vpath_mgmt registers 3974 */ 3975static enum vxge_hw_status 3976__vxge_hw_vpath_mgmt_read( 3977 struct __vxge_hw_device *hldev, 3978 struct __vxge_hw_virtualpath *vpath) 3979{ 3980 u32 i, mtu = 0, max_pyld = 0; 3981 u64 val64; 3982 enum vxge_hw_status status = VXGE_HW_OK; 3983 3984 for (i = 0; i < VXGE_HW_MAC_MAX_MAC_PORT_ID; i++) { 3985 3986 val64 = readq(&vpath->vpmgmt_reg-> 3987 rxmac_cfg0_port_vpmgmt_clone[i]); 3988 max_pyld = 3989 (u32) 3990 VXGE_HW_RXMAC_CFG0_PORT_VPMGMT_CLONE_GET_MAX_PYLD_LEN 3991 (val64); 3992 if (mtu < max_pyld) 3993 mtu = max_pyld; 3994 } 3995 3996 vpath->max_mtu = mtu + VXGE_HW_MAC_HEADER_MAX_SIZE; 3997 3998 val64 = readq(&vpath->vpmgmt_reg->xmac_vsport_choices_vp); 3999 4000 for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) { 4001 if (val64 & vxge_mBIT(i)) 4002 vpath->vsport_number = i; 4003 } 4004 4005 val64 = readq(&vpath->vpmgmt_reg->xgmac_gen_status_vpmgmt_clone); 4006 4007 if (val64 & VXGE_HW_XGMAC_GEN_STATUS_VPMGMT_CLONE_XMACJ_NTWK_OK) 4008 VXGE_HW_DEVICE_LINK_STATE_SET(vpath->hldev, VXGE_HW_LINK_UP); 4009 else 4010 VXGE_HW_DEVICE_LINK_STATE_SET(vpath->hldev, VXGE_HW_LINK_DOWN); 4011 4012 return status; 4013} 4014 4015/* 4016 * __vxge_hw_vpath_reset_check - Check if resetting the vpath completed 4017 * This routine checks the vpath_rst_in_prog register to see if 4018 * adapter completed the reset process for the vpath 4019 */ 4020static enum vxge_hw_status 4021__vxge_hw_vpath_reset_check(struct __vxge_hw_virtualpath *vpath) 4022{ 4023 enum vxge_hw_status status; 4024 4025 status = __vxge_hw_device_register_poll( 4026 &vpath->hldev->common_reg->vpath_rst_in_prog, 4027 VXGE_HW_VPATH_RST_IN_PROG_VPATH_RST_IN_PROG( 4028 1 << (16 - vpath->vp_id)), 4029 vpath->hldev->config.device_poll_millis); 4030 4031 return status; 4032} 4033 4034/* 4035 * __vxge_hw_vpath_reset 4036 * This routine resets the vpath on the device 4037 */ 4038static enum vxge_hw_status 4039__vxge_hw_vpath_reset(struct __vxge_hw_device *hldev, u32 vp_id) 4040{ 4041 u64 val64; 4042 enum vxge_hw_status status = VXGE_HW_OK; 4043 4044 val64 = VXGE_HW_CMN_RSTHDLR_CFG0_SW_RESET_VPATH(1 << (16 - vp_id)); 4045 4046 __vxge_hw_pio_mem_write32_upper((u32)vxge_bVALn(val64, 0, 32), 4047 &hldev->common_reg->cmn_rsthdlr_cfg0); 4048 4049 return status; 4050} 4051 4052/* 4053 * __vxge_hw_vpath_sw_reset 4054 * This routine resets the vpath structures 4055 */ 4056static enum vxge_hw_status 4057__vxge_hw_vpath_sw_reset(struct __vxge_hw_device *hldev, u32 vp_id) 4058{ 4059 enum vxge_hw_status status = VXGE_HW_OK; 4060 struct __vxge_hw_virtualpath *vpath; 4061 4062 vpath = (struct __vxge_hw_virtualpath *)&hldev->virtual_paths[vp_id]; 4063 4064 if (vpath->ringh) { 4065 status = __vxge_hw_ring_reset(vpath->ringh); 4066 if (status != VXGE_HW_OK) 4067 goto exit; 4068 } 4069 4070 if (vpath->fifoh) 4071 status = __vxge_hw_fifo_reset(vpath->fifoh); 4072exit: 4073 return status; 4074} 4075 4076/* 4077 * __vxge_hw_vpath_prc_configure 4078 * This routine configures the prc registers of virtual path using the config 4079 * passed 4080 */ 4081static void 4082__vxge_hw_vpath_prc_configure(struct __vxge_hw_device *hldev, u32 vp_id) 4083{ 4084 u64 val64; 4085 struct __vxge_hw_virtualpath *vpath; 4086 struct vxge_hw_vp_config *vp_config; 4087 struct vxge_hw_vpath_reg __iomem *vp_reg; 4088 4089 vpath = &hldev->virtual_paths[vp_id]; 4090 vp_reg = vpath->vp_reg; 4091 vp_config = vpath->vp_config; 4092 4093 if (vp_config->ring.enable == VXGE_HW_RING_DISABLE) 4094 return; 4095 4096 val64 = readq(&vp_reg->prc_cfg1); 4097 val64 |= VXGE_HW_PRC_CFG1_RTI_TINT_DISABLE; 4098 writeq(val64, &vp_reg->prc_cfg1); 4099 4100 val64 = readq(&vpath->vp_reg->prc_cfg6); 4101 val64 |= VXGE_HW_PRC_CFG6_DOORBELL_MODE_EN; 4102 writeq(val64, &vpath->vp_reg->prc_cfg6); 4103 4104 val64 = readq(&vp_reg->prc_cfg7); 4105 4106 if (vpath->vp_config->ring.scatter_mode != 4107 VXGE_HW_RING_SCATTER_MODE_USE_FLASH_DEFAULT) { 4108 4109 val64 &= ~VXGE_HW_PRC_CFG7_SCATTER_MODE(0x3); 4110 4111 switch (vpath->vp_config->ring.scatter_mode) { 4112 case VXGE_HW_RING_SCATTER_MODE_A: 4113 val64 |= VXGE_HW_PRC_CFG7_SCATTER_MODE( 4114 VXGE_HW_PRC_CFG7_SCATTER_MODE_A); 4115 break; 4116 case VXGE_HW_RING_SCATTER_MODE_B: 4117 val64 |= VXGE_HW_PRC_CFG7_SCATTER_MODE( 4118 VXGE_HW_PRC_CFG7_SCATTER_MODE_B); 4119 break; 4120 case VXGE_HW_RING_SCATTER_MODE_C: 4121 val64 |= VXGE_HW_PRC_CFG7_SCATTER_MODE( 4122 VXGE_HW_PRC_CFG7_SCATTER_MODE_C); 4123 break; 4124 } 4125 } 4126 4127 writeq(val64, &vp_reg->prc_cfg7); 4128 4129 writeq(VXGE_HW_PRC_CFG5_RXD0_ADD( 4130 __vxge_hw_ring_first_block_address_get( 4131 vpath->ringh) >> 3), &vp_reg->prc_cfg5); 4132 4133 val64 = readq(&vp_reg->prc_cfg4); 4134 val64 |= VXGE_HW_PRC_CFG4_IN_SVC; 4135 val64 &= ~VXGE_HW_PRC_CFG4_RING_MODE(0x3); 4136 4137 val64 |= VXGE_HW_PRC_CFG4_RING_MODE( 4138 VXGE_HW_PRC_CFG4_RING_MODE_ONE_BUFFER); 4139 4140 if (hldev->config.rth_en == VXGE_HW_RTH_DISABLE) 4141 val64 |= VXGE_HW_PRC_CFG4_RTH_DISABLE; 4142 else 4143 val64 &= ~VXGE_HW_PRC_CFG4_RTH_DISABLE; 4144 4145 writeq(val64, &vp_reg->prc_cfg4); 4146} 4147 4148/* 4149 * __vxge_hw_vpath_kdfc_configure 4150 * This routine configures the kdfc registers of virtual path using the 4151 * config passed 4152 */ 4153static enum vxge_hw_status 4154__vxge_hw_vpath_kdfc_configure(struct __vxge_hw_device *hldev, u32 vp_id) 4155{ 4156 u64 val64; 4157 u64 vpath_stride; 4158 enum vxge_hw_status status = VXGE_HW_OK; 4159 struct __vxge_hw_virtualpath *vpath; 4160 struct vxge_hw_vpath_reg __iomem *vp_reg; 4161 4162 vpath = &hldev->virtual_paths[vp_id]; 4163 vp_reg = vpath->vp_reg; 4164 status = __vxge_hw_kdfc_swapper_set(hldev->legacy_reg, vp_reg); 4165 4166 if (status != VXGE_HW_OK) 4167 goto exit; 4168 4169 val64 = readq(&vp_reg->kdfc_drbl_triplet_total); 4170 4171 vpath->max_kdfc_db = 4172 (u32)VXGE_HW_KDFC_DRBL_TRIPLET_TOTAL_GET_KDFC_MAX_SIZE( 4173 val64+1)/2; 4174 4175 if (vpath->vp_config->fifo.enable == VXGE_HW_FIFO_ENABLE) { 4176 4177 vpath->max_nofl_db = vpath->max_kdfc_db; 4178 4179 if (vpath->max_nofl_db < 4180 ((vpath->vp_config->fifo.memblock_size / 4181 (vpath->vp_config->fifo.max_frags * 4182 sizeof(struct vxge_hw_fifo_txd))) * 4183 vpath->vp_config->fifo.fifo_blocks)) { 4184 4185 return VXGE_HW_BADCFG_FIFO_BLOCKS; 4186 } 4187 val64 = VXGE_HW_KDFC_FIFO_TRPL_PARTITION_LENGTH_0( 4188 (vpath->max_nofl_db*2)-1); 4189 } 4190 4191 writeq(val64, &vp_reg->kdfc_fifo_trpl_partition); 4192 4193 writeq(VXGE_HW_KDFC_FIFO_TRPL_CTRL_TRIPLET_ENABLE, 4194 &vp_reg->kdfc_fifo_trpl_ctrl); 4195 4196 val64 = readq(&vp_reg->kdfc_trpl_fifo_0_ctrl); 4197 4198 val64 &= ~(VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_MODE(0x3) | 4199 VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_SELECT(0xFF)); 4200 4201 val64 |= VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_MODE( 4202 VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_MODE_NON_OFFLOAD_ONLY) | 4203#ifndef __BIG_ENDIAN 4204 VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_SWAP_EN | 4205#endif 4206 VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_SELECT(0); 4207 4208 writeq(val64, &vp_reg->kdfc_trpl_fifo_0_ctrl); 4209 writeq((u64)0, &vp_reg->kdfc_trpl_fifo_0_wb_address); 4210 wmb(); 4211 vpath_stride = readq(&hldev->toc_reg->toc_kdfc_vpath_stride); 4212 4213 vpath->nofl_db = 4214 (struct __vxge_hw_non_offload_db_wrapper __iomem *) 4215 (hldev->kdfc + (vp_id * 4216 VXGE_HW_TOC_KDFC_VPATH_STRIDE_GET_TOC_KDFC_VPATH_STRIDE( 4217 vpath_stride))); 4218exit: 4219 return status; 4220} 4221 4222/* 4223 * __vxge_hw_vpath_mac_configure 4224 * This routine configures the mac of virtual path using the config passed 4225 */ 4226static enum vxge_hw_status 4227__vxge_hw_vpath_mac_configure(struct __vxge_hw_device *hldev, u32 vp_id) 4228{ 4229 u64 val64; 4230 enum vxge_hw_status status = VXGE_HW_OK; 4231 struct __vxge_hw_virtualpath *vpath; 4232 struct vxge_hw_vp_config *vp_config; 4233 struct vxge_hw_vpath_reg __iomem *vp_reg; 4234 4235 vpath = &hldev->virtual_paths[vp_id]; 4236 vp_reg = vpath->vp_reg; 4237 vp_config = vpath->vp_config; 4238 4239 writeq(VXGE_HW_XMAC_VSPORT_CHOICE_VSPORT_NUMBER( 4240 vpath->vsport_number), &vp_reg->xmac_vsport_choice); 4241 4242 if (vp_config->ring.enable == VXGE_HW_RING_ENABLE) { 4243 4244 val64 = readq(&vp_reg->xmac_rpa_vcfg); 4245 4246 if (vp_config->rpa_strip_vlan_tag != 4247 VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_USE_FLASH_DEFAULT) { 4248 if (vp_config->rpa_strip_vlan_tag) 4249 val64 |= VXGE_HW_XMAC_RPA_VCFG_STRIP_VLAN_TAG; 4250 else 4251 val64 &= ~VXGE_HW_XMAC_RPA_VCFG_STRIP_VLAN_TAG; 4252 } 4253 4254 writeq(val64, &vp_reg->xmac_rpa_vcfg); 4255 val64 = readq(&vp_reg->rxmac_vcfg0); 4256 4257 if (vp_config->mtu != 4258 VXGE_HW_VPATH_USE_FLASH_DEFAULT_INITIAL_MTU) { 4259 val64 &= ~VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN(0x3fff); 4260 if ((vp_config->mtu + 4261 VXGE_HW_MAC_HEADER_MAX_SIZE) < vpath->max_mtu) 4262 val64 |= VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN( 4263 vp_config->mtu + 4264 VXGE_HW_MAC_HEADER_MAX_SIZE); 4265 else 4266 val64 |= VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN( 4267 vpath->max_mtu); 4268 } 4269 4270 writeq(val64, &vp_reg->rxmac_vcfg0); 4271 4272 val64 = readq(&vp_reg->rxmac_vcfg1); 4273 4274 val64 &= ~(VXGE_HW_RXMAC_VCFG1_RTS_RTH_MULTI_IT_BD_MODE(0x3) | 4275 VXGE_HW_RXMAC_VCFG1_RTS_RTH_MULTI_IT_EN_MODE); 4276 4277 if (hldev->config.rth_it_type == 4278 VXGE_HW_RTH_IT_TYPE_MULTI_IT) { 4279 val64 |= VXGE_HW_RXMAC_VCFG1_RTS_RTH_MULTI_IT_BD_MODE( 4280 0x2) | 4281 VXGE_HW_RXMAC_VCFG1_RTS_RTH_MULTI_IT_EN_MODE; 4282 } 4283 4284 writeq(val64, &vp_reg->rxmac_vcfg1); 4285 } 4286 return status; 4287} 4288 4289/* 4290 * __vxge_hw_vpath_tim_configure 4291 * This routine configures the tim registers of virtual path using the config 4292 * passed 4293 */ 4294static enum vxge_hw_status 4295__vxge_hw_vpath_tim_configure(struct __vxge_hw_device *hldev, u32 vp_id) 4296{ 4297 u64 val64; 4298 enum vxge_hw_status status = VXGE_HW_OK; 4299 struct __vxge_hw_virtualpath *vpath; 4300 struct vxge_hw_vpath_reg __iomem *vp_reg; 4301 struct vxge_hw_vp_config *config; 4302 4303 vpath = &hldev->virtual_paths[vp_id]; 4304 vp_reg = vpath->vp_reg; 4305 config = vpath->vp_config; 4306 4307 writeq(0, &vp_reg->tim_dest_addr); 4308 writeq(0, &vp_reg->tim_vpath_map); 4309 writeq(0, &vp_reg->tim_bitmap); 4310 writeq(0, &vp_reg->tim_remap); 4311 4312 if (config->ring.enable == VXGE_HW_RING_ENABLE) 4313 writeq(VXGE_HW_TIM_RING_ASSN_INT_NUM( 4314 (vp_id * VXGE_HW_MAX_INTR_PER_VP) + 4315 VXGE_HW_VPATH_INTR_RX), &vp_reg->tim_ring_assn); 4316 4317 val64 = readq(&vp_reg->tim_pci_cfg); 4318 val64 |= VXGE_HW_TIM_PCI_CFG_ADD_PAD; 4319 writeq(val64, &vp_reg->tim_pci_cfg); 4320 4321 if (config->fifo.enable == VXGE_HW_FIFO_ENABLE) { 4322 4323 val64 = readq(&vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_TX]); 4324 4325 if (config->tti.btimer_val != VXGE_HW_USE_FLASH_DEFAULT) { 4326 val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_BTIMER_VAL( 4327 0x3ffffff); 4328 val64 |= VXGE_HW_TIM_CFG1_INT_NUM_BTIMER_VAL( 4329 config->tti.btimer_val); 4330 } 4331 4332 val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_BITMP_EN; 4333 4334 if (config->tti.timer_ac_en != VXGE_HW_USE_FLASH_DEFAULT) { 4335 if (config->tti.timer_ac_en) 4336 val64 |= VXGE_HW_TIM_CFG1_INT_NUM_TIMER_AC; 4337 else 4338 val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_TIMER_AC; 4339 } 4340 4341 if (config->tti.timer_ci_en != VXGE_HW_USE_FLASH_DEFAULT) { 4342 if (config->tti.timer_ci_en) 4343 val64 |= VXGE_HW_TIM_CFG1_INT_NUM_TIMER_CI; 4344 else 4345 val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_TIMER_CI; 4346 } 4347 4348 if (config->tti.urange_a != VXGE_HW_USE_FLASH_DEFAULT) { 4349 val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_URNG_A(0x3f); 4350 val64 |= VXGE_HW_TIM_CFG1_INT_NUM_URNG_A( 4351 config->tti.urange_a); 4352 } 4353 4354 if (config->tti.urange_b != VXGE_HW_USE_FLASH_DEFAULT) { 4355 val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_URNG_B(0x3f); 4356 val64 |= VXGE_HW_TIM_CFG1_INT_NUM_URNG_B( 4357 config->tti.urange_b); 4358 } 4359 4360 if (config->tti.urange_c != VXGE_HW_USE_FLASH_DEFAULT) { 4361 val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_URNG_C(0x3f); 4362 val64 |= VXGE_HW_TIM_CFG1_INT_NUM_URNG_C( 4363 config->tti.urange_c); 4364 } 4365 4366 writeq(val64, &vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_TX]); 4367 vpath->tim_tti_cfg1_saved = val64; 4368 4369 val64 = readq(&vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_TX]); 4370 4371 if (config->tti.uec_a != VXGE_HW_USE_FLASH_DEFAULT) { 4372 val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_A(0xffff); 4373 val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_A( 4374 config->tti.uec_a); 4375 } 4376 4377 if (config->tti.uec_b != VXGE_HW_USE_FLASH_DEFAULT) { 4378 val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_B(0xffff); 4379 val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_B( 4380 config->tti.uec_b); 4381 } 4382 4383 if (config->tti.uec_c != VXGE_HW_USE_FLASH_DEFAULT) { 4384 val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_C(0xffff); 4385 val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_C( 4386 config->tti.uec_c); 4387 } 4388 4389 if (config->tti.uec_d != VXGE_HW_USE_FLASH_DEFAULT) { 4390 val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_D(0xffff); 4391 val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_D( 4392 config->tti.uec_d); 4393 } 4394 4395 writeq(val64, &vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_TX]); 4396 val64 = readq(&vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_TX]); 4397 4398 if (config->tti.timer_ri_en != VXGE_HW_USE_FLASH_DEFAULT) { 4399 if (config->tti.timer_ri_en) 4400 val64 |= VXGE_HW_TIM_CFG3_INT_NUM_TIMER_RI; 4401 else 4402 val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_TIMER_RI; 4403 } 4404 4405 if (config->tti.rtimer_val != VXGE_HW_USE_FLASH_DEFAULT) { 4406 val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_RTIMER_VAL( 4407 0x3ffffff); 4408 val64 |= VXGE_HW_TIM_CFG3_INT_NUM_RTIMER_VAL( 4409 config->tti.rtimer_val); 4410 } 4411 4412 if (config->tti.util_sel != VXGE_HW_USE_FLASH_DEFAULT) { 4413 val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL(0x3f); 4414 val64 |= VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL(vp_id); 4415 } 4416 4417 if (config->tti.ltimer_val != VXGE_HW_USE_FLASH_DEFAULT) { 4418 val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_LTIMER_VAL( 4419 0x3ffffff); 4420 val64 |= VXGE_HW_TIM_CFG3_INT_NUM_LTIMER_VAL( 4421 config->tti.ltimer_val); 4422 } 4423 4424 writeq(val64, &vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_TX]); 4425 vpath->tim_tti_cfg3_saved = val64; 4426 } 4427 4428 if (config->ring.enable == VXGE_HW_RING_ENABLE) { 4429 4430 val64 = readq(&vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_RX]); 4431 4432 if (config->rti.btimer_val != VXGE_HW_USE_FLASH_DEFAULT) { 4433 val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_BTIMER_VAL( 4434 0x3ffffff); 4435 val64 |= VXGE_HW_TIM_CFG1_INT_NUM_BTIMER_VAL( 4436 config->rti.btimer_val); 4437 } 4438 4439 val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_BITMP_EN; 4440 4441 if (config->rti.timer_ac_en != VXGE_HW_USE_FLASH_DEFAULT) { 4442 if (config->rti.timer_ac_en) 4443 val64 |= VXGE_HW_TIM_CFG1_INT_NUM_TIMER_AC; 4444 else 4445 val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_TIMER_AC; 4446 } 4447 4448 if (config->rti.timer_ci_en != VXGE_HW_USE_FLASH_DEFAULT) { 4449 if (config->rti.timer_ci_en) 4450 val64 |= VXGE_HW_TIM_CFG1_INT_NUM_TIMER_CI; 4451 else 4452 val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_TIMER_CI; 4453 } 4454 4455 if (config->rti.urange_a != VXGE_HW_USE_FLASH_DEFAULT) { 4456 val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_URNG_A(0x3f); 4457 val64 |= VXGE_HW_TIM_CFG1_INT_NUM_URNG_A( 4458 config->rti.urange_a); 4459 } 4460 4461 if (config->rti.urange_b != VXGE_HW_USE_FLASH_DEFAULT) { 4462 val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_URNG_B(0x3f); 4463 val64 |= VXGE_HW_TIM_CFG1_INT_NUM_URNG_B( 4464 config->rti.urange_b); 4465 } 4466 4467 if (config->rti.urange_c != VXGE_HW_USE_FLASH_DEFAULT) { 4468 val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_URNG_C(0x3f); 4469 val64 |= VXGE_HW_TIM_CFG1_INT_NUM_URNG_C( 4470 config->rti.urange_c); 4471 } 4472 4473 writeq(val64, &vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_RX]); 4474 vpath->tim_rti_cfg1_saved = val64; 4475 4476 val64 = readq(&vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_RX]); 4477 4478 if (config->rti.uec_a != VXGE_HW_USE_FLASH_DEFAULT) { 4479 val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_A(0xffff); 4480 val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_A( 4481 config->rti.uec_a); 4482 } 4483 4484 if (config->rti.uec_b != VXGE_HW_USE_FLASH_DEFAULT) { 4485 val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_B(0xffff); 4486 val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_B( 4487 config->rti.uec_b); 4488 } 4489 4490 if (config->rti.uec_c != VXGE_HW_USE_FLASH_DEFAULT) { 4491 val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_C(0xffff); 4492 val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_C( 4493 config->rti.uec_c); 4494 } 4495 4496 if (config->rti.uec_d != VXGE_HW_USE_FLASH_DEFAULT) { 4497 val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_D(0xffff); 4498 val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_D( 4499 config->rti.uec_d); 4500 } 4501 4502 writeq(val64, &vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_RX]); 4503 val64 = readq(&vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_RX]); 4504 4505 if (config->rti.timer_ri_en != VXGE_HW_USE_FLASH_DEFAULT) { 4506 if (config->rti.timer_ri_en) 4507 val64 |= VXGE_HW_TIM_CFG3_INT_NUM_TIMER_RI; 4508 else 4509 val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_TIMER_RI; 4510 } 4511 4512 if (config->rti.rtimer_val != VXGE_HW_USE_FLASH_DEFAULT) { 4513 val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_RTIMER_VAL( 4514 0x3ffffff); 4515 val64 |= VXGE_HW_TIM_CFG3_INT_NUM_RTIMER_VAL( 4516 config->rti.rtimer_val); 4517 } 4518 4519 if (config->rti.util_sel != VXGE_HW_USE_FLASH_DEFAULT) { 4520 val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL(0x3f); 4521 val64 |= VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL(vp_id); 4522 } 4523 4524 if (config->rti.ltimer_val != VXGE_HW_USE_FLASH_DEFAULT) { 4525 val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_LTIMER_VAL( 4526 0x3ffffff); 4527 val64 |= VXGE_HW_TIM_CFG3_INT_NUM_LTIMER_VAL( 4528 config->rti.ltimer_val); 4529 } 4530 4531 writeq(val64, &vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_RX]); 4532 vpath->tim_rti_cfg3_saved = val64; 4533 } 4534 4535 val64 = 0; 4536 writeq(val64, &vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_EINTA]); 4537 writeq(val64, &vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_EINTA]); 4538 writeq(val64, &vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_EINTA]); 4539 writeq(val64, &vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_BMAP]); 4540 writeq(val64, &vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_BMAP]); 4541 writeq(val64, &vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_BMAP]); 4542 4543 val64 = VXGE_HW_TIM_WRKLD_CLC_WRKLD_EVAL_PRD(150); 4544 val64 |= VXGE_HW_TIM_WRKLD_CLC_WRKLD_EVAL_DIV(0); 4545 val64 |= VXGE_HW_TIM_WRKLD_CLC_CNT_RX_TX(3); 4546 writeq(val64, &vp_reg->tim_wrkld_clc); 4547 4548 return status; 4549} 4550 4551/* 4552 * __vxge_hw_vpath_initialize 4553 * This routine is the final phase of init which initializes the 4554 * registers of the vpath using the configuration passed. 4555 */ 4556static enum vxge_hw_status 4557__vxge_hw_vpath_initialize(struct __vxge_hw_device *hldev, u32 vp_id) 4558{ 4559 u64 val64; 4560 u32 val32; 4561 enum vxge_hw_status status = VXGE_HW_OK; 4562 struct __vxge_hw_virtualpath *vpath; 4563 struct vxge_hw_vpath_reg __iomem *vp_reg; 4564 4565 vpath = &hldev->virtual_paths[vp_id]; 4566 4567 if (!(hldev->vpath_assignments & vxge_mBIT(vp_id))) { 4568 status = VXGE_HW_ERR_VPATH_NOT_AVAILABLE; 4569 goto exit; 4570 } 4571 vp_reg = vpath->vp_reg; 4572 4573 status = __vxge_hw_vpath_swapper_set(vpath->vp_reg); 4574 if (status != VXGE_HW_OK) 4575 goto exit; 4576 4577 status = __vxge_hw_vpath_mac_configure(hldev, vp_id); 4578 if (status != VXGE_HW_OK) 4579 goto exit; 4580 4581 status = __vxge_hw_vpath_kdfc_configure(hldev, vp_id); 4582 if (status != VXGE_HW_OK) 4583 goto exit; 4584 4585 status = __vxge_hw_vpath_tim_configure(hldev, vp_id); 4586 if (status != VXGE_HW_OK) 4587 goto exit; 4588 4589 val64 = readq(&vp_reg->rtdma_rd_optimization_ctrl); 4590 4591 /* Get MRRS value from device control */ 4592 status = __vxge_hw_vpath_pci_read(vpath, 1, 0x78, &val32); 4593 if (status == VXGE_HW_OK) { 4594 val32 = (val32 & VXGE_HW_PCI_EXP_DEVCTL_READRQ) >> 12; 4595 val64 &= 4596 ~(VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_FILL_THRESH(7)); 4597 val64 |= 4598 VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_FILL_THRESH(val32); 4599 4600 val64 |= VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_WAIT_FOR_SPACE; 4601 } 4602 4603 val64 &= ~(VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_ADDR_BDRY(7)); 4604 val64 |= 4605 VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_ADDR_BDRY( 4606 VXGE_HW_MAX_PAYLOAD_SIZE_512); 4607 4608 val64 |= VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_ADDR_BDRY_EN; 4609 writeq(val64, &vp_reg->rtdma_rd_optimization_ctrl); 4610 4611exit: 4612 return status; 4613} 4614 4615/* 4616 * __vxge_hw_vp_terminate - Terminate Virtual Path structure 4617 * This routine closes all channels it opened and freeup memory 4618 */ 4619static void __vxge_hw_vp_terminate(struct __vxge_hw_device *hldev, u32 vp_id) 4620{ 4621 struct __vxge_hw_virtualpath *vpath; 4622 4623 vpath = &hldev->virtual_paths[vp_id]; 4624 4625 if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) 4626 goto exit; 4627 4628 VXGE_HW_DEVICE_TIM_INT_MASK_RESET(vpath->hldev->tim_int_mask0, 4629 vpath->hldev->tim_int_mask1, vpath->vp_id); 4630 hldev->stats.hw_dev_info_stats.vpath_info[vpath->vp_id] = NULL; 4631 4632 /* If the whole struct __vxge_hw_virtualpath is zeroed, nothing will 4633 * work after the interface is brought down. 4634 */ 4635 spin_lock(&vpath->lock); 4636 vpath->vp_open = VXGE_HW_VP_NOT_OPEN; 4637 spin_unlock(&vpath->lock); 4638 4639 vpath->vpmgmt_reg = NULL; 4640 vpath->nofl_db = NULL; 4641 vpath->max_mtu = 0; 4642 vpath->vsport_number = 0; 4643 vpath->max_kdfc_db = 0; 4644 vpath->max_nofl_db = 0; 4645 vpath->ringh = NULL; 4646 vpath->fifoh = NULL; 4647 memset(&vpath->vpath_handles, 0, sizeof(struct list_head)); 4648 vpath->stats_block = 0; 4649 vpath->hw_stats = NULL; 4650 vpath->hw_stats_sav = NULL; 4651 vpath->sw_stats = NULL; 4652 4653exit: 4654 return; 4655} 4656 4657/* 4658 * __vxge_hw_vp_initialize - Initialize Virtual Path structure 4659 * This routine is the initial phase of init which resets the vpath and 4660 * initializes the software support structures. 4661 */ 4662static enum vxge_hw_status 4663__vxge_hw_vp_initialize(struct __vxge_hw_device *hldev, u32 vp_id, 4664 struct vxge_hw_vp_config *config) 4665{ 4666 struct __vxge_hw_virtualpath *vpath; 4667 enum vxge_hw_status status = VXGE_HW_OK; 4668 4669 if (!(hldev->vpath_assignments & vxge_mBIT(vp_id))) { 4670 status = VXGE_HW_ERR_VPATH_NOT_AVAILABLE; 4671 goto exit; 4672 } 4673 4674 vpath = &hldev->virtual_paths[vp_id]; 4675 4676 spin_lock_init(&vpath->lock); 4677 vpath->vp_id = vp_id; 4678 vpath->vp_open = VXGE_HW_VP_OPEN; 4679 vpath->hldev = hldev; 4680 vpath->vp_config = config; 4681 vpath->vp_reg = hldev->vpath_reg[vp_id]; 4682 vpath->vpmgmt_reg = hldev->vpmgmt_reg[vp_id]; 4683 4684 __vxge_hw_vpath_reset(hldev, vp_id); 4685 4686 status = __vxge_hw_vpath_reset_check(vpath); 4687 if (status != VXGE_HW_OK) { 4688 memset(vpath, 0, sizeof(struct __vxge_hw_virtualpath)); 4689 goto exit; 4690 } 4691 4692 status = __vxge_hw_vpath_mgmt_read(hldev, vpath); 4693 if (status != VXGE_HW_OK) { 4694 memset(vpath, 0, sizeof(struct __vxge_hw_virtualpath)); 4695 goto exit; 4696 } 4697 4698 INIT_LIST_HEAD(&vpath->vpath_handles); 4699 4700 vpath->sw_stats = &hldev->stats.sw_dev_info_stats.vpath_info[vp_id]; 4701 4702 VXGE_HW_DEVICE_TIM_INT_MASK_SET(hldev->tim_int_mask0, 4703 hldev->tim_int_mask1, vp_id); 4704 4705 status = __vxge_hw_vpath_initialize(hldev, vp_id); 4706 if (status != VXGE_HW_OK) 4707 __vxge_hw_vp_terminate(hldev, vp_id); 4708exit: 4709 return status; 4710} 4711 4712/* 4713 * vxge_hw_vpath_mtu_set - Set MTU. 4714 * Set new MTU value. Example, to use jumbo frames: 4715 * vxge_hw_vpath_mtu_set(my_device, 9600); 4716 */ 4717enum vxge_hw_status 4718vxge_hw_vpath_mtu_set(struct __vxge_hw_vpath_handle *vp, u32 new_mtu) 4719{ 4720 u64 val64; 4721 enum vxge_hw_status status = VXGE_HW_OK; 4722 struct __vxge_hw_virtualpath *vpath; 4723 4724 if (vp == NULL) { 4725 status = VXGE_HW_ERR_INVALID_HANDLE; 4726 goto exit; 4727 } 4728 vpath = vp->vpath; 4729 4730 new_mtu += VXGE_HW_MAC_HEADER_MAX_SIZE; 4731 4732 if ((new_mtu < VXGE_HW_MIN_MTU) || (new_mtu > vpath->max_mtu)) 4733 status = VXGE_HW_ERR_INVALID_MTU_SIZE; 4734 4735 val64 = readq(&vpath->vp_reg->rxmac_vcfg0); 4736 4737 val64 &= ~VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN(0x3fff); 4738 val64 |= VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN(new_mtu); 4739 4740 writeq(val64, &vpath->vp_reg->rxmac_vcfg0); 4741 4742 vpath->vp_config->mtu = new_mtu - VXGE_HW_MAC_HEADER_MAX_SIZE; 4743 4744exit: 4745 return status; 4746} 4747 4748/* 4749 * vxge_hw_vpath_stats_enable - Enable vpath h/wstatistics. 4750 * Enable the DMA vpath statistics. The function is to be called to re-enable 4751 * the adapter to update stats into the host memory 4752 */ 4753static enum vxge_hw_status 4754vxge_hw_vpath_stats_enable(struct __vxge_hw_vpath_handle *vp) 4755{ 4756 enum vxge_hw_status status = VXGE_HW_OK; 4757 struct __vxge_hw_virtualpath *vpath; 4758 4759 vpath = vp->vpath; 4760 4761 if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) { 4762 status = VXGE_HW_ERR_VPATH_NOT_OPEN; 4763 goto exit; 4764 } 4765 4766 memcpy(vpath->hw_stats_sav, vpath->hw_stats, 4767 sizeof(struct vxge_hw_vpath_stats_hw_info)); 4768 4769 status = __vxge_hw_vpath_stats_get(vpath, vpath->hw_stats); 4770exit: 4771 return status; 4772} 4773 4774/* 4775 * __vxge_hw_blockpool_block_allocate - Allocates a block from block pool 4776 * This function allocates a block from block pool or from the system 4777 */ 4778static struct __vxge_hw_blockpool_entry * 4779__vxge_hw_blockpool_block_allocate(struct __vxge_hw_device *devh, u32 size) 4780{ 4781 struct __vxge_hw_blockpool_entry *entry = NULL; 4782 struct __vxge_hw_blockpool *blockpool; 4783 4784 blockpool = &devh->block_pool; 4785 4786 if (size == blockpool->block_size) { 4787 4788 if (!list_empty(&blockpool->free_block_list)) 4789 entry = (struct __vxge_hw_blockpool_entry *) 4790 list_first_entry(&blockpool->free_block_list, 4791 struct __vxge_hw_blockpool_entry, 4792 item); 4793 4794 if (entry != NULL) { 4795 list_del(&entry->item); 4796 blockpool->pool_size--; 4797 } 4798 } 4799 4800 if (entry != NULL) 4801 __vxge_hw_blockpool_blocks_add(blockpool); 4802 4803 return entry; 4804} 4805 4806/* 4807 * vxge_hw_vpath_open - Open a virtual path on a given adapter 4808 * This function is used to open access to virtual path of an 4809 * adapter for offload, GRO operations. This function returns 4810 * synchronously. 4811 */ 4812enum vxge_hw_status 4813vxge_hw_vpath_open(struct __vxge_hw_device *hldev, 4814 struct vxge_hw_vpath_attr *attr, 4815 struct __vxge_hw_vpath_handle **vpath_handle) 4816{ 4817 struct __vxge_hw_virtualpath *vpath; 4818 struct __vxge_hw_vpath_handle *vp; 4819 enum vxge_hw_status status; 4820 4821 vpath = &hldev->virtual_paths[attr->vp_id]; 4822 4823 if (vpath->vp_open == VXGE_HW_VP_OPEN) { 4824 status = VXGE_HW_ERR_INVALID_STATE; 4825 goto vpath_open_exit1; 4826 } 4827 4828 status = __vxge_hw_vp_initialize(hldev, attr->vp_id, 4829 &hldev->config.vp_config[attr->vp_id]); 4830 if (status != VXGE_HW_OK) 4831 goto vpath_open_exit1; 4832 4833 vp = vzalloc(sizeof(struct __vxge_hw_vpath_handle)); 4834 if (vp == NULL) { 4835 status = VXGE_HW_ERR_OUT_OF_MEMORY; 4836 goto vpath_open_exit2; 4837 } 4838 4839 vp->vpath = vpath; 4840 4841 if (vpath->vp_config->fifo.enable == VXGE_HW_FIFO_ENABLE) { 4842 status = __vxge_hw_fifo_create(vp, &attr->fifo_attr); 4843 if (status != VXGE_HW_OK) 4844 goto vpath_open_exit6; 4845 } 4846 4847 if (vpath->vp_config->ring.enable == VXGE_HW_RING_ENABLE) { 4848 status = __vxge_hw_ring_create(vp, &attr->ring_attr); 4849 if (status != VXGE_HW_OK) 4850 goto vpath_open_exit7; 4851 4852 __vxge_hw_vpath_prc_configure(hldev, attr->vp_id); 4853 } 4854 4855 vpath->fifoh->tx_intr_num = 4856 (attr->vp_id * VXGE_HW_MAX_INTR_PER_VP) + 4857 VXGE_HW_VPATH_INTR_TX; 4858 4859 vpath->stats_block = __vxge_hw_blockpool_block_allocate(hldev, 4860 VXGE_HW_BLOCK_SIZE); 4861 if (vpath->stats_block == NULL) { 4862 status = VXGE_HW_ERR_OUT_OF_MEMORY; 4863 goto vpath_open_exit8; 4864 } 4865 4866 vpath->hw_stats = vpath->stats_block->memblock; 4867 memset(vpath->hw_stats, 0, 4868 sizeof(struct vxge_hw_vpath_stats_hw_info)); 4869 4870 hldev->stats.hw_dev_info_stats.vpath_info[attr->vp_id] = 4871 vpath->hw_stats; 4872 4873 vpath->hw_stats_sav = 4874 &hldev->stats.hw_dev_info_stats.vpath_info_sav[attr->vp_id]; 4875 memset(vpath->hw_stats_sav, 0, 4876 sizeof(struct vxge_hw_vpath_stats_hw_info)); 4877 4878 writeq(vpath->stats_block->dma_addr, &vpath->vp_reg->stats_cfg); 4879 4880 status = vxge_hw_vpath_stats_enable(vp); 4881 if (status != VXGE_HW_OK) 4882 goto vpath_open_exit8; 4883 4884 list_add(&vp->item, &vpath->vpath_handles); 4885 4886 hldev->vpaths_deployed |= vxge_mBIT(vpath->vp_id); 4887 4888 *vpath_handle = vp; 4889 4890 attr->fifo_attr.userdata = vpath->fifoh; 4891 attr->ring_attr.userdata = vpath->ringh; 4892 4893 return VXGE_HW_OK; 4894 4895vpath_open_exit8: 4896 if (vpath->ringh != NULL) 4897 __vxge_hw_ring_delete(vp); 4898vpath_open_exit7: 4899 if (vpath->fifoh != NULL) 4900 __vxge_hw_fifo_delete(vp); 4901vpath_open_exit6: 4902 vfree(vp); 4903vpath_open_exit2: 4904 __vxge_hw_vp_terminate(hldev, attr->vp_id); 4905vpath_open_exit1: 4906 4907 return status; 4908} 4909 4910/** 4911 * vxge_hw_vpath_rx_doorbell_post - Close the handle got from previous vpath 4912 * (vpath) open 4913 * @vp: Handle got from previous vpath open 4914 * 4915 * This function is used to close access to virtual path opened 4916 * earlier. 4917 */ 4918void vxge_hw_vpath_rx_doorbell_init(struct __vxge_hw_vpath_handle *vp) 4919{ 4920 struct __vxge_hw_virtualpath *vpath = vp->vpath; 4921 struct __vxge_hw_ring *ring = vpath->ringh; 4922 struct vxgedev *vdev = netdev_priv(vpath->hldev->ndev); 4923 u64 new_count, val64, val164; 4924 4925 if (vdev->titan1) { 4926 new_count = readq(&vpath->vp_reg->rxdmem_size); 4927 new_count &= 0x1fff; 4928 } else 4929 new_count = ring->config->ring_blocks * VXGE_HW_BLOCK_SIZE / 8; 4930 4931 val164 = VXGE_HW_RXDMEM_SIZE_PRC_RXDMEM_SIZE(new_count); 4932 4933 writeq(VXGE_HW_PRC_RXD_DOORBELL_NEW_QW_CNT(val164), 4934 &vpath->vp_reg->prc_rxd_doorbell); 4935 readl(&vpath->vp_reg->prc_rxd_doorbell); 4936 4937 val164 /= 2; 4938 val64 = readq(&vpath->vp_reg->prc_cfg6); 4939 val64 = VXGE_HW_PRC_CFG6_RXD_SPAT(val64); 4940 val64 &= 0x1ff; 4941 4942 /* 4943 * Each RxD is of 4 qwords 4944 */ 4945 new_count -= (val64 + 1); 4946 val64 = min(val164, new_count) / 4; 4947 4948 ring->rxds_limit = min(ring->rxds_limit, val64); 4949 if (ring->rxds_limit < 4) 4950 ring->rxds_limit = 4; 4951} 4952 4953/* 4954 * __vxge_hw_blockpool_block_free - Frees a block from block pool 4955 * @devh: Hal device 4956 * @entry: Entry of block to be freed 4957 * 4958 * This function frees a block from block pool 4959 */ 4960static void 4961__vxge_hw_blockpool_block_free(struct __vxge_hw_device *devh, 4962 struct __vxge_hw_blockpool_entry *entry) 4963{ 4964 struct __vxge_hw_blockpool *blockpool; 4965 4966 blockpool = &devh->block_pool; 4967 4968 if (entry->length == blockpool->block_size) { 4969 list_add(&entry->item, &blockpool->free_block_list); 4970 blockpool->pool_size++; 4971 } 4972 4973 __vxge_hw_blockpool_blocks_remove(blockpool); 4974} 4975 4976/* 4977 * vxge_hw_vpath_close - Close the handle got from previous vpath (vpath) open 4978 * This function is used to close access to virtual path opened 4979 * earlier. 4980 */ 4981enum vxge_hw_status vxge_hw_vpath_close(struct __vxge_hw_vpath_handle *vp) 4982{ 4983 struct __vxge_hw_virtualpath *vpath = NULL; 4984 struct __vxge_hw_device *devh = NULL; 4985 u32 vp_id = vp->vpath->vp_id; 4986 u32 is_empty = TRUE; 4987 enum vxge_hw_status status = VXGE_HW_OK; 4988 4989 vpath = vp->vpath; 4990 devh = vpath->hldev; 4991 4992 if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) { 4993 status = VXGE_HW_ERR_VPATH_NOT_OPEN; 4994 goto vpath_close_exit; 4995 } 4996 4997 list_del(&vp->item); 4998 4999 if (!list_empty(&vpath->vpath_handles)) { 5000 list_add(&vp->item, &vpath->vpath_handles); 5001 is_empty = FALSE; 5002 } 5003 5004 if (!is_empty) { 5005 status = VXGE_HW_FAIL; 5006 goto vpath_close_exit; 5007 } 5008 5009 devh->vpaths_deployed &= ~vxge_mBIT(vp_id); 5010 5011 if (vpath->ringh != NULL) 5012 __vxge_hw_ring_delete(vp); 5013 5014 if (vpath->fifoh != NULL) 5015 __vxge_hw_fifo_delete(vp); 5016 5017 if (vpath->stats_block != NULL) 5018 __vxge_hw_blockpool_block_free(devh, vpath->stats_block); 5019 5020 vfree(vp); 5021 5022 __vxge_hw_vp_terminate(devh, vp_id); 5023 5024vpath_close_exit: 5025 return status; 5026} 5027 5028/* 5029 * vxge_hw_vpath_reset - Resets vpath 5030 * This function is used to request a reset of vpath 5031 */ 5032enum vxge_hw_status vxge_hw_vpath_reset(struct __vxge_hw_vpath_handle *vp) 5033{ 5034 enum vxge_hw_status status; 5035 u32 vp_id; 5036 struct __vxge_hw_virtualpath *vpath = vp->vpath; 5037 5038 vp_id = vpath->vp_id; 5039 5040 if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) { 5041 status = VXGE_HW_ERR_VPATH_NOT_OPEN; 5042 goto exit; 5043 } 5044 5045 status = __vxge_hw_vpath_reset(vpath->hldev, vp_id); 5046 if (status == VXGE_HW_OK) 5047 vpath->sw_stats->soft_reset_cnt++; 5048exit: 5049 return status; 5050} 5051 5052/* 5053 * vxge_hw_vpath_recover_from_reset - Poll for reset complete and re-initialize. 5054 * This function poll's for the vpath reset completion and re initializes 5055 * the vpath. 5056 */ 5057enum vxge_hw_status 5058vxge_hw_vpath_recover_from_reset(struct __vxge_hw_vpath_handle *vp) 5059{ 5060 struct __vxge_hw_virtualpath *vpath = NULL; 5061 enum vxge_hw_status status; 5062 struct __vxge_hw_device *hldev; 5063 u32 vp_id; 5064 5065 vp_id = vp->vpath->vp_id; 5066 vpath = vp->vpath; 5067 hldev = vpath->hldev; 5068 5069 if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) { 5070 status = VXGE_HW_ERR_VPATH_NOT_OPEN; 5071 goto exit; 5072 } 5073 5074 status = __vxge_hw_vpath_reset_check(vpath); 5075 if (status != VXGE_HW_OK) 5076 goto exit; 5077 5078 status = __vxge_hw_vpath_sw_reset(hldev, vp_id); 5079 if (status != VXGE_HW_OK) 5080 goto exit; 5081 5082 status = __vxge_hw_vpath_initialize(hldev, vp_id); 5083 if (status != VXGE_HW_OK) 5084 goto exit; 5085 5086 if (vpath->ringh != NULL) 5087 __vxge_hw_vpath_prc_configure(hldev, vp_id); 5088 5089 memset(vpath->hw_stats, 0, 5090 sizeof(struct vxge_hw_vpath_stats_hw_info)); 5091 5092 memset(vpath->hw_stats_sav, 0, 5093 sizeof(struct vxge_hw_vpath_stats_hw_info)); 5094 5095 writeq(vpath->stats_block->dma_addr, 5096 &vpath->vp_reg->stats_cfg); 5097 5098 status = vxge_hw_vpath_stats_enable(vp); 5099 5100exit: 5101 return status; 5102} 5103 5104/* 5105 * vxge_hw_vpath_enable - Enable vpath. 5106 * This routine clears the vpath reset thereby enabling a vpath 5107 * to start forwarding frames and generating interrupts. 5108 */ 5109void 5110vxge_hw_vpath_enable(struct __vxge_hw_vpath_handle *vp) 5111{ 5112 struct __vxge_hw_device *hldev; 5113 u64 val64; 5114 5115 hldev = vp->vpath->hldev; 5116 5117 val64 = VXGE_HW_CMN_RSTHDLR_CFG1_CLR_VPATH_RESET( 5118 1 << (16 - vp->vpath->vp_id)); 5119 5120 __vxge_hw_pio_mem_write32_upper((u32)vxge_bVALn(val64, 0, 32), 5121 &hldev->common_reg->cmn_rsthdlr_cfg1); 5122} 5123