1 /* 2 * Copyright 2014-2017 Cavium, Inc. 3 * The contents of this file are subject to the terms of the Common Development 4 * and Distribution License, v.1, (the "License"). 5 * 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the License at available 9 * at http://opensource.org/licenses/CDDL-1.0 10 * 11 * See the License for the specific language governing permissions and 12 * limitations under the License. 13 */ 14 15 #include "lm5706.h" 16 #if !defined(LINUX) && !defined(SOLARIS) 17 #include "string.h" // needed by some OS for memset 18 #pragma warning(disable:28718) 19 #endif 20 21 22 /******************************************************************************* 23 * Description: 24 * 25 * Return: 26 ******************************************************************************/ 27 void 28 lm_abort( 29 lm_device_t *pdev, 30 u32_t abort_op, 31 u32_t idx) 32 { 33 if(abort_op == ABORT_OP_RX_CHAIN) 34 { 35 lm_recv_abort(pdev, idx); 36 } 37 else if(abort_op == ABORT_OP_TX_CHAIN) 38 { 39 lm_send_abort(pdev, idx); 40 } 41 else 42 { 43 DbgBreakMsg("Invalid abort.\n"); 44 } 45 } /* lm_abort */ 46 47 48 49 /******************************************************************************* 50 * Description: 51 * 52 * Return: 53 ******************************************************************************/ 54 STATIC char * 55 val_to_decimal_string( 56 char *str_buf, 57 u32_t buf_size, 58 u32_t val) 59 { 60 u32_t digit; 61 62 if(buf_size == 0) 63 { 64 return str_buf; 65 } 66 67 digit = val % 10; 68 val = val / 10; 69 70 if(val) 71 { 72 buf_size--; 73 str_buf = val_to_decimal_string(str_buf, buf_size, val); 74 } 75 76 *str_buf = '0' + digit; 77 78 str_buf++; 79 80 return str_buf; 81 } /* val_to_decimal_string */ 82 83 84 85 /******************************************************************************* 86 * Description: 87 * 88 * Return: 89 ******************************************************************************/ 90 STATIC u32_t 91 build_ver_string( 92 char *str_buf, 93 u32_t buf_size, 94 u8_t major_ver, 95 u8_t minor_ver, 96 u8_t rel_num, 97 u8_t fix_num) 98 { 99 char *p; 100 101 if(buf_size == 0) 102 { 103 return 0; 104 } 105 106 p = str_buf; 107 108 if(buf_size - (p - str_buf) > 1) 109 { 110 *p = 'v'; 111 p++; 112 } 113 114 if(buf_size - (p - str_buf) > 1) 115 { 116 p = val_to_decimal_string( 117 p, 118 buf_size - (u32_t) PTR_SUB(p, str_buf), 119 major_ver); 120 } 121 122 if(buf_size - (p - str_buf) > 1) 123 { 124 *p = '.'; 125 p++; 126 } 127 128 if(buf_size - (u32_t) PTR_SUB(p, str_buf) > 1) 129 { 130 p = val_to_decimal_string( 131 p, 132 buf_size - (u32_t) PTR_SUB(p, str_buf), 133 minor_ver); 134 } 135 136 if(buf_size - (u32_t) PTR_SUB(p, str_buf) > 1) 137 { 138 *p = '.'; 139 p++; 140 } 141 142 if(buf_size - (u32_t) PTR_SUB(p, str_buf) > 1) 143 { 144 p = val_to_decimal_string( 145 p, 146 buf_size - (u32_t) PTR_SUB(p, str_buf), 147 rel_num); 148 } 149 150 if(buf_size - (u32_t) PTR_SUB(p, str_buf) > 1) 151 { 152 *p = '.'; 153 p++; 154 } 155 156 if(buf_size - (u32_t) PTR_SUB(p, str_buf) > 1) 157 { 158 p = val_to_decimal_string( 159 p, 160 buf_size - (u32_t) PTR_SUB(p, str_buf), 161 fix_num); 162 } 163 164 if(buf_size - (u32_t) PTR_SUB(p, str_buf) > 1) 165 { 166 *p = '.'; 167 p++; 168 } 169 170 if(buf_size - (u32_t) PTR_SUB(p, str_buf) > 1) 171 { 172 #if DBG 173 *p = 'd'; 174 #else 175 *p = 'r'; 176 #endif 177 178 p++; 179 } 180 181 if(buf_size - (u32_t) PTR_SUB(p, str_buf) > 1) 182 { 183 #if DBG 184 *p = 'b'; 185 #else 186 *p = 't'; 187 #endif 188 189 p++; 190 } 191 192 if(buf_size - (u32_t) PTR_SUB(p, str_buf) > 1) 193 { 194 #if DBG 195 *p = 'g'; 196 #else 197 *p = 'l'; 198 #endif 199 200 p++; 201 } 202 203 *p = 0; 204 p++; 205 206 return (u32_t) PTR_SUB(p, str_buf); 207 } /* build_ver_string */ 208 209 210 211 /******************************************************************************* 212 * Description: 213 * 214 * Return: 215 ******************************************************************************/ 216 STATIC void 217 get_max_conns( 218 lm_device_t *pdev, 219 u32_t *max_toe_conn, 220 u32_t *max_iscsi_conn, 221 u32_t *max_iscsi_pending_tasks) 222 { 223 u32_t max_lic_conn; 224 u32_t max_res_conn; 225 u32_t res_flags; 226 227 /* get resource reservation flag. */ 228 REG_RD_IND( 229 pdev, 230 pdev->hw_info.shmem_base + 231 OFFSETOF(shmem_region_t, 232 dev_info.port_feature_config.resource.res_cfg), 233 &res_flags); 234 235 /* get max_lic_conn for toe. */ 236 REG_RD_IND( 237 pdev, 238 pdev->hw_info.shmem_base + 239 OFFSETOF(shmem_region_t, fw_lic_key.max_toe_conn), 240 &max_lic_conn); 241 242 max_lic_conn &= 0xffff; 243 244 if(max_lic_conn) 245 { 246 max_lic_conn ^= FW_ENCODE_16BIT_PATTERN; 247 248 if(max_lic_conn == 0xffff) 249 { 250 max_lic_conn = 1024; 251 } 252 } 253 254 /* get max_res_conn for toe. */ 255 if(res_flags & RES_RES_CFG_VALID) 256 { 257 if(res_flags & RES_RES_CFG_L2) 258 { 259 REG_RD_IND( 260 pdev, 261 pdev->hw_info.shmem_base + 262 OFFSETOF(shmem_region_t, 263 dev_info.port_feature_config.resource.conn_resource1), 264 &max_res_conn); 265 /* 266 * if(max_res_conn == 0 || !(res_flags & RES_RES_CFG_FCFS_DISABLED)) 267 * CQ#42214 HH, SK and HYF all agreed on removing the test 268 * for max_res_conn == 0 269 */ 270 if (!(res_flags & RES_RES_CFG_FCFS_DISABLED)) 271 { 272 max_res_conn = 1024; 273 } 274 } 275 else 276 { 277 max_res_conn = 0; 278 } 279 } 280 else 281 { 282 max_res_conn = 1024; 283 } 284 285 *max_toe_conn = (max_lic_conn < max_res_conn) ? max_lic_conn: max_res_conn; 286 287 /* get iscsi pending tasks. */ 288 if((res_flags & RES_RES_CFG_VALID) && (res_flags & RES_RES_CFG_ISCSI)) 289 { 290 REG_RD_IND( 291 pdev, 292 pdev->hw_info.shmem_base + 293 OFFSETOF(shmem_region_t, 294 dev_info.port_feature_config.resource.conn_resource3), 295 max_iscsi_pending_tasks); 296 297 *max_iscsi_pending_tasks &= RES_CONN_ISCSI_PTASK_MASK; 298 299 if(*max_iscsi_pending_tasks == 0 || *max_iscsi_pending_tasks > 128) 300 { 301 *max_iscsi_pending_tasks = 128; 302 } 303 } 304 else 305 { 306 *max_iscsi_pending_tasks = 128; 307 *max_iscsi_conn = 0; 308 } 309 310 REG_RD_IND( 311 pdev, 312 pdev->hw_info.shmem_base + 313 OFFSETOF(shmem_region_t, fw_lic_key.max_iscsi_trgt_conn), 314 &max_lic_conn); 315 316 if(max_lic_conn) 317 { 318 max_lic_conn ^= FW_ENCODE_32BIT_PATTERN; 319 max_lic_conn >>= 16; 320 } 321 322 *max_iscsi_conn = max_lic_conn; 323 324 /* no license information. */ 325 if(*max_toe_conn == 0) 326 { 327 if(pdev->hw_info.svid == 0x103c) /* HP device. */ 328 { 329 *max_toe_conn = 1024; 330 } 331 else if(CHIP_REV(pdev) == CHIP_REV_IKOS || 332 CHIP_REV(pdev) == CHIP_REV_FPGA) 333 { 334 *max_toe_conn = 32; 335 } 336 } 337 338 /* cq#39856 - iSCSI Device Disappears from System after reboot. */ 339 if(*max_iscsi_conn == 0) 340 { 341 if(pdev->hw_info.svid == 0x103c) /* HP device. */ 342 { 343 *max_iscsi_conn = 1024; 344 } 345 else if(CHIP_REV(pdev) == CHIP_REV_IKOS || 346 CHIP_REV(pdev) == CHIP_REV_FPGA) 347 { 348 *max_iscsi_conn = 32; 349 } 350 } 351 } /* get_max_conns */ 352 353 354 355 /******************************************************************************* 356 * Description: 357 * 358 * Return: 359 ******************************************************************************/ 360 lm_status_t 361 lm_get_dev_info( 362 lm_device_t *pdev) 363 { 364 typedef struct _param_entry_t 365 { 366 /* Ideally, we want to save the address of the parameter here. 367 * However, some compiler will not allow us to dynamically 368 * initialize the pointer to a parameter in the table below. 369 * As an alternative, we will save the offset to the parameter 370 * from pdev device structure. */ 371 u32_t offset; 372 373 /* Parameter default value. */ 374 u32_t asic_default; 375 u32_t fpga_ikos_default; 376 377 /* Limit checking is diabled if min and max are zeros. */ 378 u32_t min; 379 u32_t max; 380 } param_entry_t; 381 382 #define _OFFSET(_name) (OFFSETOF(lm_device_t, params._name)) 383 #define PARAM_VAL(_pdev, _entry) \ 384 (*((u32_t *) ((u8_t *) (_pdev) + (_entry)->offset))) 385 #define SET_PARAM_VAL(_pdev, _entry, _val) \ 386 *((u32_t *) ((u8_t *) (_pdev) + (_entry)->offset)) = (_val) 387 388 static param_entry_t param_list[] = 389 { 390 /* asic fpga/ikos 391 offset default default min max */ 392 { _OFFSET(mtu), 1500, 1500, 1500, 9018 }, 393 { _OFFSET(l2_rx_desc_cnt[0]), 200, 150, 0, 0 }, 394 { _OFFSET(l2_rx_desc_cnt[1]), 0, 0, 0, 0 }, 395 { _OFFSET(l2_rx_desc_cnt[2]), 0, 0, 0, 0 }, 396 { _OFFSET(l2_rx_desc_cnt[3]), 0, 0, 0, 0 }, 397 { _OFFSET(l2_rx_desc_cnt[4]), 0, 0, 0, 0 }, 398 { _OFFSET(l2_rx_desc_cnt[5]), 0, 0, 0, 0 }, 399 { _OFFSET(l2_rx_desc_cnt[6]), 0, 0, 0, 0 }, 400 { _OFFSET(l2_rx_desc_cnt[7]), 0, 0, 0, 0 }, 401 { _OFFSET(l2_rx_desc_cnt[8]), 0, 0, 0, 0 }, 402 { _OFFSET(l2_rx_desc_cnt[9]), 0, 0, 0, 0 }, 403 { _OFFSET(l2_rx_desc_cnt[10]), 0, 0, 0, 0 }, 404 { _OFFSET(l2_rx_desc_cnt[11]), 0, 0, 0, 0 }, 405 #if 0 406 { _OFFSET(l2_rx_desc_cnt[12]), 0, 0, 0, 0 }, 407 { _OFFSET(l2_rx_desc_cnt[13]), 0, 0, 0, 0 }, 408 { _OFFSET(l2_rx_desc_cnt[14]), 0, 0, 0, 0 }, 409 { _OFFSET(l2_rx_desc_cnt[15]), 0, 0, 0, 0 }, 410 #endif 411 412 /* The maximum page count is chosen to prevent us from having 413 * more than 32767 pending entries at any one time. */ 414 { _OFFSET(l2_tx_bd_page_cnt[0]), 2, 2, 1, 127 }, 415 { _OFFSET(l2_tx_bd_page_cnt[1]), 1, 1, 1, 127 }, 416 { _OFFSET(l2_tx_bd_page_cnt[2]), 1, 1, 1, 127 }, 417 { _OFFSET(l2_tx_bd_page_cnt[3]), 1, 1, 1, 127 }, 418 { _OFFSET(l2_tx_bd_page_cnt[4]), 1, 1, 1, 127 }, 419 { _OFFSET(l2_tx_bd_page_cnt[5]), 1, 1, 1, 127 }, 420 { _OFFSET(l2_tx_bd_page_cnt[6]), 1, 1, 1, 127 }, 421 { _OFFSET(l2_tx_bd_page_cnt[7]), 1, 1, 1, 127 }, 422 { _OFFSET(l2_tx_bd_page_cnt[8]), 1, 1, 1, 127 }, 423 { _OFFSET(l2_tx_bd_page_cnt[9]), 1, 1, 1, 127 }, 424 { _OFFSET(l2_tx_bd_page_cnt[10]), 1, 1, 1, 127 }, 425 { _OFFSET(l2_tx_bd_page_cnt[11]), 1, 1, 1, 127 }, 426 427 { _OFFSET(l2_rx_bd_page_cnt[0]), 2, 2, 1, 127 }, 428 { _OFFSET(l2_rx_bd_page_cnt[1]), 1, 1, 1, 127 }, 429 { _OFFSET(l2_rx_bd_page_cnt[2]), 1, 1, 1, 127 }, 430 { _OFFSET(l2_rx_bd_page_cnt[3]), 1, 1, 1, 127 }, 431 { _OFFSET(l2_rx_bd_page_cnt[4]), 1, 1, 1, 127 }, 432 { _OFFSET(l2_rx_bd_page_cnt[5]), 1, 1, 1, 127 }, 433 { _OFFSET(l2_rx_bd_page_cnt[6]), 1, 1, 1, 127 }, 434 { _OFFSET(l2_rx_bd_page_cnt[7]), 1, 1, 1, 127 }, 435 { _OFFSET(l2_rx_bd_page_cnt[8]), 1, 1, 1, 127 }, 436 { _OFFSET(l2_rx_bd_page_cnt[9]), 1, 1, 1, 127 }, 437 { _OFFSET(l2_rx_bd_page_cnt[10]), 1, 1, 1, 127 }, 438 { _OFFSET(l2_rx_bd_page_cnt[11]), 1, 1, 1, 127 }, 439 #if 0 440 { _OFFSET(l2_rx_bd_page_cnt[12]), 1, 1, 1, 127 }, 441 { _OFFSET(l2_rx_bd_page_cnt[13]), 1, 1, 1, 127 }, 442 { _OFFSET(l2_rx_bd_page_cnt[14]), 1, 1, 1, 127 }, 443 { _OFFSET(l2_rx_bd_page_cnt[15]), 1, 1, 1, 127 }, 444 #endif 445 446 { _OFFSET(l4_tx_bd_page_cnt), 1, 1, 1, 255 }, 447 { _OFFSET(limit_l4_tx_bd_cnt), 0, 0, 0, 0 }, 448 { _OFFSET(l4_rx_bd_page_cnt), 1, 1, 1, 255 }, 449 { _OFFSET(limit_l4_rx_bd_cnt), 0, 0, 0, 0 }, 450 451 #ifndef EXCLUDE_KQE_SUPPORT 452 #if INCLUDE_OFLD_SUPPORT 453 { _OFFSET(kwq_page_cnt), 4, 2, 1, 255 }, 454 { _OFFSET(kcq_page_cnt), 32, 32, 1, 255 }, 455 { _OFFSET(kcq_history_size), 0x80, 0x80, 0, 0 }, 456 #else 457 /* Kernel queues are used when RSS or TCP offload is enabled. 458 * When RSS is enabled, the upper module should modify the 459 * default settings for these parameters. */ 460 { _OFFSET(kwq_page_cnt), 0, 0, 0, 0 }, 461 { _OFFSET(kcq_page_cnt), 0, 0, 0, 0 }, 462 { _OFFSET(kcq_history_size), 0, 0, 0, 0 }, 463 #endif 464 465 /* Connection kcqe/kwqe history. */ 466 { _OFFSET(con_kcqe_history_size), 0, 0, 0, 0 }, 467 { _OFFSET(con_kwqe_history_size), 0, 0, 0, 0 }, 468 #endif 469 470 { _OFFSET(gen_bd_page_cnt), 2, 2, 1, 127 }, 471 { _OFFSET(max_gen_buf_cnt), 0x8000, 0x8000, 0, 0 }, 472 { _OFFSET(gen_buf_per_alloc), 0x4, 0x4, 0, 0 }, 473 474 { _OFFSET(copy_buffered_data), 0, 0, 0, 0 }, 475 { _OFFSET(rcv_buffer_offset), 0x38, 0x38, 0, 0 }, 476 { _OFFSET(enable_syn_rcvq), 0, 0, 0, 0 }, 477 478 { _OFFSET(hcopy_desc_cnt), 0, 0, 0, 0 }, 479 { _OFFSET(hcopy_bd_page_cnt), 2, 2, 1, 127 }, 480 { _OFFSET(buffered_kcqe_cnt), 0x80, 0x80, 0, 0 }, 481 482 { _OFFSET(deferred_kcqe_cnt), 0x100, 0x100, 0, 0 }, 483 484 { _OFFSET(test_mode), 0x60, 0x60, 0, 0 }, 485 { _OFFSET(ofld_cap), 0, 0, 0, 0 }, 486 { _OFFSET(wol_cap), 0, 0, 0, 0 }, 487 { _OFFSET(flow_ctrl_cap), 0, 0, 0, 0 }, 488 { _OFFSET(req_medium), 0, 0, 0, 0xfffff }, 489 { _OFFSET(selective_autoneg), 0, 0, 0, 0 }, 490 { _OFFSET(wire_speed), 1, 0, 0, 0 }, 491 { _OFFSET(phy_addr), 1, 0, 0, 0 }, 492 { _OFFSET(phy_int_mode), 2, 2, 0, 0 }, 493 { _OFFSET(link_chng_mode), 2, 2, 0, 0 }, 494 495 { _OFFSET(hc_timer_mode), 0, 0, 0, 0 }, 496 { _OFFSET(ind_comp_limit), 200, 100, 0, 0 }, 497 { _OFFSET(tx_quick_cons_trip_int), 3, 10, 0, 0 }, 498 { _OFFSET(tx_quick_cons_trip), 3, 30, 0, 0 }, 499 { _OFFSET(tx_ticks_int), 30, 10, 0, 0 }, 500 { _OFFSET(tx_ticks), 60, 200, 0, 0 }, 501 { _OFFSET(rx_quick_cons_trip_int), 1, 3, 0, 0 }, 502 { _OFFSET(rx_quick_cons_trip), 2, 1, 0, 0 }, 503 { _OFFSET(rx_ticks_int), 15, 5, 0, 0 }, 504 { _OFFSET(rx_ticks), 45, 1, 0, 0 }, 505 { _OFFSET(comp_prod_trip_int), 2, 3, 0, 0 }, 506 { _OFFSET(comp_prod_trip), 4, 1, 0, 0 }, 507 { _OFFSET(com_ticks_int), 64, 5, 0, 0 }, 508 { _OFFSET(com_ticks), 220, 1, 0, 0 }, 509 { _OFFSET(cmd_ticks_int), 64, 5, 0, 0 }, 510 { _OFFSET(cmd_ticks), 220, 1, 0, 0 }, 511 { _OFFSET(stats_ticks), 1000000, 1000000, 0, 0 }, 512 513 /* Xinan per-processor HC configuration. */ 514 { _OFFSET(psb_tx_cons_trip), 0x100010,0x100010,0, 0 }, 515 { _OFFSET(psb_tx_ticks), 0x100040,0x100040,0, 0 }, 516 { _OFFSET(psb_rx_cons_trip), 0x100010,0x100010,0, 0 }, 517 { _OFFSET(psb_rx_ticks), 0x80020, 0x80020, 0, 0 }, 518 { _OFFSET(psb_comp_prod_trip), 0x80008, 0x80008, 0, 0 }, 519 { _OFFSET(psb_com_ticks), 0x400040,0x400040,0, 0 }, 520 { _OFFSET(psb_cmd_ticks), 0x400040,0x400040,0, 0 }, 521 { _OFFSET(psb_period_ticks), 0, 0, 0, 0 }, 522 523 { _OFFSET(enable_fir), 1, 1, 0, 0 }, 524 { _OFFSET(num_rchans), 5, 5, 0, 0 }, 525 { _OFFSET(num_wchans), 3, 3, 0, 0 }, 526 527 /* One some system, with one_tdma disabled, we will get data 528 * corruption. Currently this looks like a chipset bug. The 529 * chip group will continue to look into this. So for now, we 530 * will enable one_tdma for all chip revisions. */ 531 { _OFFSET(one_tdma), 0, 0, 0, 0 }, 532 533 { _OFFSET(ping_pong_dma), 0, 0, 0, 0 }, 534 { _OFFSET(tmr_reload_value1), 0x6c627970, 0, 0, 0 }, 535 { _OFFSET(keep_vlan_tag), 0, 0, 0, 0 }, 536 537 { _OFFSET(enable_remote_phy), 0, 0, 0, 0 }, 538 { _OFFSET(rphy_req_medium), 0, 0, 0, 0 }, 539 { _OFFSET(rphy_flow_ctrl_cap), 0, 0, 0, 0 }, 540 { _OFFSET(rphy_selective_autoneg), 0, 0, 0, 0 }, 541 { _OFFSET(rphy_wire_speed), 1, 0, 0, 0 }, 542 543 { _OFFSET(bin_mq_mode), 0, 0, 0, 0 }, 544 { _OFFSET(validate_l4_data), 0, 0, 0, 0 }, 545 { _OFFSET(disable_pcie_nfr), 0, 0, 0, 0 }, 546 { _OFFSET(fw_flow_control), 0, 0, 0, 0 }, 547 { _OFFSET(fw_flow_control_wait), 0xffff, 0xffff, 0, 0xffff }, 548 { _OFFSET(ena_large_grc_timeout), 0, 0, 0, 0 }, 549 { _OFFSET(flow_control_reporting_mode), 0, 0, 0, 0 }, 550 { 0, 0, 0, 0, 0 } 551 }; 552 553 lm_status_t lm_status; 554 param_entry_t *param; 555 u32_t val; 556 557 DbgMessage(pdev, INFORMi, "### lm_get_dev_info\n"); 558 559 /* Get PCI device and vendor id. */ 560 lm_status = mm_read_pci( 561 pdev, 562 OFFSETOF(reg_space_t, pci_config.pcicfg_vendor_id), 563 &val); 564 if(lm_status != LM_STATUS_SUCCESS) 565 { 566 return lm_status; 567 } 568 569 pdev->hw_info.vid = (u16_t) val; 570 DbgMessage1(pdev, INFORMi, "vid 0x%x\n", pdev->hw_info.vid); 571 572 pdev->hw_info.did = (u16_t) (val >> 16); 573 DbgMessage1(pdev, INFORMi, "did 0x%x\n", pdev->hw_info.did); 574 575 /* Get subsystem and subvendor id. */ 576 lm_status = mm_read_pci( 577 pdev, 578 OFFSETOF(reg_space_t, pci_config.pcicfg_subsystem_vendor_id), 579 &val); 580 if(lm_status != LM_STATUS_SUCCESS) 581 { 582 return lm_status; 583 } 584 585 pdev->hw_info.svid = (u16_t) val; 586 DbgMessage1(pdev, INFORMi, "svid 0x%x\n", pdev->hw_info.svid); 587 588 pdev->hw_info.ssid = (u16_t) (val >> 16); 589 DbgMessage1(pdev, INFORMi, "ssid 0x%x\n", pdev->hw_info.ssid); 590 591 /* Get IRQ, and interrupt pin. */ 592 lm_status = mm_read_pci( 593 pdev, 594 OFFSETOF(reg_space_t, pci_config.pcicfg_int_line), 595 &val); 596 if(lm_status != LM_STATUS_SUCCESS) 597 { 598 return lm_status; 599 } 600 601 pdev->hw_info.irq = (u8_t) val; 602 DbgMessage1(pdev, INFORMi, "IRQ 0x%x\n", pdev->hw_info.irq); 603 604 pdev->hw_info.int_pin = (u8_t) (val >> 8); 605 DbgMessage1(pdev, INFORMi, "Int pin 0x%x\n", pdev->hw_info.int_pin); 606 607 /* Get cache line size. */ 608 lm_status = mm_read_pci( 609 pdev, 610 OFFSETOF(reg_space_t, pci_config.pcicfg_cache_line_size), 611 &val); 612 if(lm_status != LM_STATUS_SUCCESS) 613 { 614 return lm_status; 615 } 616 617 pdev->hw_info.cache_line_size = (u8_t) val; 618 DbgMessage1(pdev, INFORMi, "Cache line size 0x%x\n", (u8_t) val); 619 620 pdev->hw_info.latency_timer = (u8_t) (val >> 8); 621 DbgMessage1(pdev, INFORMi, "Latency timer 0x%x\n", (u8_t) (val >> 8)); 622 623 /* Get PCI revision id. */ 624 lm_status = mm_read_pci( 625 pdev, 626 OFFSETOF(reg_space_t, pci_config.pcicfg_class_code), 627 &val); 628 if(lm_status != LM_STATUS_SUCCESS) 629 { 630 return lm_status; 631 } 632 633 pdev->hw_info.rev_id = (u8_t) val; 634 DbgMessage1(pdev, INFORMi, "Revision id 0x%x\n", pdev->hw_info.rev_id); 635 636 /* Get the base address. */ 637 lm_status = mm_read_pci( 638 pdev, 639 OFFSETOF(reg_space_t, pci_config.pcicfg_bar_1), 640 &val); 641 if(lm_status != LM_STATUS_SUCCESS) 642 { 643 return lm_status; 644 } 645 646 #ifndef CONFIG_PPC64 647 pdev->hw_info.mem_base.as_u32.low = val & 0xfffffff0; 648 #endif 649 650 DbgMessage1(pdev, INFORMi, "Mem base low 0x%x\n", pdev->hw_info.mem_base.as_u32.low); 651 652 val = 0; 653 654 lm_status = mm_read_pci( 655 pdev, 656 OFFSETOF(reg_space_t, pci_config.pcicfg_bar_2), 657 &val); 658 if(lm_status != LM_STATUS_SUCCESS) 659 { 660 return lm_status; 661 } 662 663 #ifndef CONFIG_PPC64 664 pdev->hw_info.mem_base.as_u32.high = val; 665 #endif 666 667 DbgMessage1(pdev, INFORMi, "Mem base high 0x%x\n", 668 pdev->hw_info.mem_base.as_u32.high); 669 670 /* Enable PCI bus master. This is supposed to be enabled by the 671 * BIOS, however, BIOS on older systems may not set this bit. */ 672 lm_status = mm_read_pci( 673 pdev, 674 OFFSETOF(reg_space_t, pci_config.pcicfg_command), 675 &val); 676 if(lm_status != LM_STATUS_SUCCESS) 677 { 678 return lm_status; 679 } 680 681 /* Error out if memory map is NOT enabled. This could occur if the 682 * BIOS is not able to reserve an address range for the device. */ 683 if(!(val & PCICFG_COMMAND_MEM_SPACE)) 684 { 685 DbgBreakMsg("MEM_SPACE not enabled.\n"); 686 687 return LM_STATUS_FAILURE; 688 } 689 690 val |= PCICFG_COMMAND_BUS_MASTER; 691 692 lm_status = mm_write_pci( 693 pdev, 694 OFFSETOF(reg_space_t, pci_config.pcicfg_command), 695 val); 696 if(lm_status != LM_STATUS_SUCCESS) 697 { 698 return lm_status; 699 } 700 701 /* Configure byte swap and enable write to the reg_window registers. */ 702 val = PCICFG_MISC_CONFIG_REG_WINDOW_ENA | 703 PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP; 704 lm_status = mm_write_pci( 705 pdev, 706 OFFSETOF(reg_space_t, pci_config.pcicfg_misc_config), 707 val); 708 if(lm_status != LM_STATUS_SUCCESS) 709 { 710 return lm_status; 711 } 712 713 /* Get the bar size at register 0x408 via PCI configuration indirect. */ 714 lm_status = mm_write_pci( 715 pdev, 716 OFFSETOF(pci_config_t, pcicfg_reg_window_address), 717 OFFSETOF(reg_space_t, pci.pci_config_2)); 718 if(lm_status != LM_STATUS_SUCCESS) 719 { 720 return lm_status; 721 } 722 723 lm_status = mm_read_pci( 724 pdev, 725 OFFSETOF(pci_config_t, pcicfg_reg_window), 726 &val); 727 if(lm_status != LM_STATUS_SUCCESS) 728 { 729 return lm_status; 730 } 731 732 val &= PCI_CONFIG_2_BAR1_SIZE; 733 if(val == PCI_CONFIG_2_BAR1_SIZE_DISABLED || 734 val > PCI_CONFIG_2_BAR1_SIZE_1G) 735 { 736 DbgBreakMsg("Invalid bar size.\n"); 737 738 return LM_STATUS_FAILURE; 739 } 740 741 pdev->hw_info.bar_size = 1 << (val+15); 742 DbgMessage1(pdev, INFORM, "bar_size 0x%x\n", pdev->hw_info.bar_size); 743 744 /* Map memory base to system address space. */ 745 pdev->vars.regview = (reg_space_t *) mm_map_io_base( 746 pdev, 747 pdev->hw_info.mem_base, 748 pdev->hw_info.bar_size); 749 if(pdev->vars.regview == NULL) 750 { 751 return LM_STATUS_FAILURE; 752 } 753 DbgMessage1(pdev, INFORMi, "Mapped base %p\n", pdev->vars.regview); 754 755 #if DBG 756 /* Make sure byte swapping is properly configured. */ 757 REG_RD(pdev, pci.pci_swap_diag0, &val); 758 759 DbgBreakIf(val != 0x1020304); 760 #endif 761 762 /* Get the chip revision id and number. */ 763 REG_RD(pdev, misc.misc_id, &pdev->hw_info.chip_id); 764 DbgMessage1(pdev, INFORMi, "chip id 0x%x\n", pdev->hw_info.chip_id); 765 766 if(CHIP_NUM(pdev) == CHIP_NUM_5709) 767 { 768 pdev->hw_info.bus_mode = BUS_MODE_PCIE; 769 } 770 else 771 { 772 /* Get bus information. */ 773 REG_RD(pdev, pci_config.pcicfg_misc_status, &val); 774 775 if(val & PCICFG_MISC_STATUS_32BIT_DET) 776 { 777 pdev->hw_info.bus_width = BUS_WIDTH_32_BIT; 778 DbgMessage(pdev, INFORM, "32bit bus width.\n"); 779 } 780 else 781 { 782 pdev->hw_info.bus_width = BUS_WIDTH_64_BIT; 783 DbgMessage(pdev, INFORM, "64bit bus width.\n"); 784 } 785 786 if(val & PCICFG_MISC_STATUS_PCIX_DET) 787 { 788 pdev->hw_info.bus_mode = BUS_MODE_PCIX; 789 DbgMessage(pdev, INFORM, "PCIX bus detected.\n"); 790 791 REG_RD(pdev, pci_config.pcicfg_pci_clock_control_bits, &val); 792 switch(val & PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET) 793 { 794 case PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_133MHZ: 795 pdev->hw_info.bus_speed = BUS_SPEED_133_MHZ; 796 DbgMessage(pdev, INFORM, "Bus speed is 133Mhz.\n"); 797 break; 798 799 case PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_95MHZ: 800 pdev->hw_info.bus_speed = BUS_SPEED_100_MHZ; 801 DbgMessage(pdev, INFORM, "Bus speed is 100Mhz.\n"); 802 break; 803 804 case PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_66MHZ: 805 case PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_80MHZ: 806 pdev->hw_info.bus_speed = BUS_SPEED_66_MHZ; 807 DbgMessage(pdev, INFORM, "Bus speed is 66Mhz.\n"); 808 break; 809 810 case PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_48MHZ: 811 case PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_55MHZ: 812 pdev->hw_info.bus_speed = BUS_SPEED_50_MHZ; 813 DbgMessage(pdev, INFORM, "Bus speed is 50Mhz.\n"); 814 break; 815 816 case PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET: 817 case PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_32MHZ: 818 case PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_38MHZ: 819 default: 820 pdev->hw_info.bus_speed = BUS_SPEED_33_MHZ; 821 DbgMessage(pdev, INFORM, "Bus speed is 33Mhz.\n"); 822 break; 823 } 824 } 825 else 826 { 827 pdev->hw_info.bus_mode = BUS_MODE_PCI; 828 DbgMessage(pdev, INFORM, "Conventional PCI bus detected.\n"); 829 830 if(val & PCICFG_MISC_STATUS_M66EN) 831 { 832 pdev->hw_info.bus_speed = BUS_SPEED_66_MHZ; 833 DbgMessage(pdev, INFORM, "Bus speed is 66Mhz.\n"); 834 } 835 else 836 { 837 pdev->hw_info.bus_speed = BUS_SPEED_33_MHZ; 838 DbgMessage(pdev, INFORM, "Bus speed is 33Mhz.\n"); 839 } 840 } 841 } 842 843 if(CHIP_ID(pdev) == CHIP_ID_5706_A0 || CHIP_ID(pdev) == CHIP_ID_5706_A1) 844 { 845 REG_RD_OFFSET( 846 pdev, 847 OFFSETOF(reg_space_t, pci_config.pcicfg_command), 848 &val); 849 850 /* 5706A0 may falsely detect SERR and PERR. */ 851 if(CHIP_ID(pdev) == CHIP_ID_5706_A0) 852 { 853 val &= ~(PCICFG_COMMAND_SERR_ENA | PCICFG_COMMAND_PERR_ENA); 854 } 855 856 /* 5706A1 PCI 64-bit. */ 857 else if(pdev->hw_info.bus_mode == BUS_MODE_PCI && 858 pdev->hw_info.bus_width == BUS_WIDTH_64_BIT) 859 { 860 /* E4_5706A1_577: PERR IS INCORRECTLY GENERATED IN PCI 64-BIT. 861 Description: If the data on the upper AD and CBE busses 862 do not match the parity of PAR64 during a 32-bit target 863 access, a parity error is incorrectly generated. This 864 happens only after a 64-bit master DMA operation has been 865 done by the chip. 866 Scope: All PCI 64-bit systems. 867 Impact: Ability to indicate a real parity error is lost. 868 Workaround: Driver needs to clear PERR_EN. */ 869 val &= ~PCICFG_COMMAND_PERR_ENA; 870 } 871 872 REG_WR_OFFSET( 873 pdev, 874 OFFSETOF(reg_space_t, pci_config.pcicfg_command), 875 val); 876 } 877 else if(CHIP_ID(pdev) == CHIP_ID_5708_A0) 878 { 879 /* 5708A0 errata. */ 880 REG_RD_OFFSET( 881 pdev, 882 OFFSETOF(reg_space_t, pci_config.pcicfg_command), 883 &val); 884 885 val &= ~(PCICFG_COMMAND_SERR_ENA | PCICFG_COMMAND_PERR_ENA); 886 887 REG_WR_OFFSET( 888 pdev, 889 OFFSETOF(reg_space_t, pci_config.pcicfg_command), 890 val); 891 } 892 893 /* Get the EPB info. */ 894 if(CHIP_NUM(pdev) == CHIP_NUM_5708) 895 { 896 REG_RD_IND(pdev, 0x240000+0x18, &val); 897 pdev->hw_info.pcie_bus_num = (u8_t) val; 898 899 REG_RD_IND(pdev, 0x240000+0x6c, &val); 900 pdev->hw_info.pcie_max_width = (u8_t) ((val & 0x3f0) >> 4); 901 902 switch(val & 0xf) 903 { 904 case 1: 905 pdev->hw_info.pcie_max_speed = PCIE_SPEED_2_5_G; 906 break; 907 908 default: 909 pdev->hw_info.pcie_max_speed = 0; 910 break; 911 } 912 913 REG_RD_IND(pdev, 0x240000+0x70, &val); 914 pdev->hw_info.pcie_width = (u8_t) ((val & 0x3f00000) >> 20); 915 916 switch(val & 0xf0000) 917 { 918 case 0x10000: 919 pdev->hw_info.pcie_speed = PCIE_SPEED_2_5_G; 920 break; 921 922 default: 923 pdev->hw_info.pcie_speed = 0; 924 break; 925 } 926 } 927 else if(CHIP_NUM(pdev) == CHIP_NUM_5709) 928 { 929 REG_RD(pdev, pci_config.pcicfg_link_capability, &val); 930 pdev->hw_info.pcie_max_width = 931 (u8_t) ((val & PCICFG_LINK_CAPABILITY_MAX_LINK_WIDTH) >> 4); 932 switch (val & PCICFG_LINK_CAPABILITY_MAX_LINK_SPEED) 933 { 934 case PCICFG_LINK_CAPABILITY_MAX_LINK_SPEED_5: 935 pdev->hw_info.pcie_max_speed = PCIE_SPEED_5_G; 936 break; 937 case PCICFG_LINK_CAPABILITY_MAX_LINK_SPEED_2_5: 938 pdev->hw_info.pcie_max_speed = PCIE_SPEED_2_5_G; 939 break; 940 default: 941 pdev->hw_info.pcie_max_speed = 0; 942 break; 943 } 944 945 REG_RD(pdev, pci_config.pcicfg_link_status, &val); 946 pdev->hw_info.pcie_width = 947 (u8_t) ((val & PCICFG_LINK_STATUS_NEG_LINK_WIDTH) >> 4); 948 switch (val & PCICFG_LINK_STATUS_SPEED) 949 { 950 case PCICFG_LINK_CAPABILITY_MAX_LINK_SPEED_5: 951 pdev->hw_info.pcie_speed = PCIE_SPEED_5_G; 952 break; 953 case PCICFG_LINK_CAPABILITY_MAX_LINK_SPEED_2_5: 954 pdev->hw_info.pcie_speed = PCIE_SPEED_2_5_G; 955 break; 956 default: 957 pdev->hw_info.pcie_speed = 0; 958 break; 959 } 960 961 REG_RD_IND(pdev, OFFSETOF(reg_space_t, mcp.mcp_toe_id), &val); 962 if(val & MCP_TOE_ID_FUNCTION_ID) 963 { 964 pdev->hw_info.mac_id = 1; 965 } 966 } 967 968 /* Get firmware share memory base address. */ 969 REG_RD_IND( 970 pdev, 971 MCP_SCRATCHPAD_START + OFFSETOF(shm_hdr_t, shm_hdr_signature), 972 &val); 973 if((val & SHM_ADDR_SIGN_MASK) == SHM_ADDR_SIGNATURE) 974 { 975 REG_RD_IND( 976 pdev, 977 MCP_SCRATCHPAD_START + 978 OFFSETOF(shm_hdr_t, shm_addr[pdev->hw_info.mac_id]), 979 &pdev->hw_info.shmem_base); 980 } 981 else 982 { 983 /* Pre v1.3.2 bootcode. */ 984 pdev->hw_info.shmem_base = HOST_VIEW_SHMEM_BASE; 985 } 986 987 /* Get the hw config word. */ 988 REG_RD_IND( 989 pdev, 990 pdev->hw_info.shmem_base + 991 OFFSETOF(shmem_region_t, dev_info.shared_hw_config.config), 992 &val); 993 pdev->hw_info.nvm_hw_config = val; 994 995 get_max_conns( 996 pdev, 997 &pdev->hw_info.max_toe_conn, 998 &pdev->hw_info.max_iscsi_conn, 999 &pdev->hw_info.max_iscsi_pending_tasks); 1000 1001 /* Get the permanent MAC address. */ 1002 REG_RD_IND( 1003 pdev, 1004 pdev->hw_info.shmem_base + 1005 OFFSETOF(shmem_region_t, dev_info.port_hw_config.mac_upper), 1006 &val); 1007 pdev->hw_info.mac_addr[0] = (u8_t) (val >> 8); 1008 pdev->hw_info.mac_addr[1] = (u8_t) val; 1009 1010 REG_RD_IND( 1011 pdev, 1012 pdev->hw_info.shmem_base + 1013 OFFSETOF(shmem_region_t, dev_info.port_hw_config.mac_lower), 1014 &val); 1015 1016 pdev->hw_info.mac_addr[2] = (u8_t) (val >> 24); 1017 pdev->hw_info.mac_addr[3] = (u8_t) (val >> 16); 1018 pdev->hw_info.mac_addr[4] = (u8_t) (val >> 8); 1019 pdev->hw_info.mac_addr[5] = (u8_t) val; 1020 1021 /* Get iSCSI MAC address. */ 1022 REG_RD_IND( 1023 pdev, 1024 pdev->hw_info.shmem_base + 1025 OFFSETOF( 1026 shmem_region_t, 1027 dev_info.port_hw_config.iscsi_mac_upper), 1028 &val); 1029 pdev->hw_info.iscsi_mac_addr[0] = (u8_t) (val >> 8); 1030 pdev->hw_info.iscsi_mac_addr[1] = (u8_t) val; 1031 1032 REG_RD_IND( 1033 pdev, 1034 pdev->hw_info.shmem_base + 1035 OFFSETOF( 1036 shmem_region_t, 1037 dev_info.port_hw_config.iscsi_mac_lower), 1038 &val); 1039 pdev->hw_info.iscsi_mac_addr[2] = (u8_t) (val >> 24); 1040 pdev->hw_info.iscsi_mac_addr[3] = (u8_t) (val >> 16); 1041 pdev->hw_info.iscsi_mac_addr[4] = (u8_t) (val >> 8); 1042 pdev->hw_info.iscsi_mac_addr[5] = (u8_t) val; 1043 1044 DbgMessage6(pdev, INFORM, "mac addr: %02x %02x %02x %02x %02x %02x\n", 1045 pdev->hw_info.mac_addr[0], 1046 pdev->hw_info.mac_addr[1], 1047 pdev->hw_info.mac_addr[2], 1048 pdev->hw_info.mac_addr[3], 1049 pdev->hw_info.mac_addr[4], 1050 pdev->hw_info.mac_addr[5]); 1051 1052 DbgBreakIf(LM_DRIVER_MAJOR_VER > 255); 1053 DbgBreakIf(LM_DRIVER_MINOR_VER > 255); 1054 DbgBreakIf(LM_DRIVER_REL_NUM > 255); 1055 DbgBreakIf(LM_DRIVER_FIX_NUM > 255); 1056 1057 pdev->ver_num = 1058 (LM_DRIVER_MAJOR_VER << 24) | 1059 (LM_DRIVER_MINOR_VER << 16) | 1060 (LM_DRIVER_REL_NUM << 8) | 1061 LM_DRIVER_FIX_NUM; 1062 1063 (void) build_ver_string( 1064 (char *)pdev->ver_str, 1065 sizeof(pdev->ver_str), 1066 LM_DRIVER_MAJOR_VER, 1067 LM_DRIVER_MINOR_VER, 1068 LM_DRIVER_REL_NUM, 1069 LM_DRIVER_FIX_NUM); 1070 1071 pdev->params.mac_addr[0] = pdev->hw_info.mac_addr[0]; 1072 pdev->params.mac_addr[1] = pdev->hw_info.mac_addr[1]; 1073 pdev->params.mac_addr[2] = pdev->hw_info.mac_addr[2]; 1074 pdev->params.mac_addr[3] = pdev->hw_info.mac_addr[3]; 1075 pdev->params.mac_addr[4] = pdev->hw_info.mac_addr[4]; 1076 pdev->params.mac_addr[5] = pdev->hw_info.mac_addr[5]; 1077 1078 /* Initialize the default parameters. */ 1079 param = param_list; 1080 while(param->offset) 1081 { 1082 if(CHIP_REV(pdev) == CHIP_REV_FPGA || CHIP_REV(pdev) == CHIP_REV_IKOS) 1083 { 1084 SET_PARAM_VAL(pdev, param, param->fpga_ikos_default); 1085 } 1086 else 1087 { 1088 SET_PARAM_VAL(pdev, param, param->asic_default); 1089 } 1090 1091 param++; 1092 } 1093 1094 if(CHIP_REV(pdev) == CHIP_REV_FPGA || CHIP_REV(pdev) == CHIP_REV_IKOS) 1095 { 1096 pdev->params.test_mode |= TEST_MODE_INIT_GEN_BUF_DATA; 1097 pdev->params.test_mode |= TEST_MODE_SAVE_DUMMY_DMA_DATA; 1098 pdev->params.test_mode |= TEST_MODE_IGNORE_SHMEM_SIGNATURE; 1099 pdev->params.test_mode |= TEST_MODE_DRIVER_PULSE_ALWAYS_ALIVE; 1100 } 1101 1102 /* Some chipsets are not capabable of handling multiple 1103 * read requests. Currently we will get data corrupt on 1104 * Intel 840/860 chipset when one_tdma is not enabled. */ 1105 if(pdev->hw_info.bus_mode == BUS_MODE_PCI) 1106 { 1107 if((CHIP_NUM(pdev)==CHIP_NUM_5706 || CHIP_NUM(pdev)==CHIP_NUM_5708) && 1108 (CHIP_REV(pdev)==CHIP_REV_FPGA || CHIP_REV(pdev)==CHIP_REV_IKOS)) 1109 { 1110 pdev->params.ping_pong_dma = FALSE; 1111 } 1112 else 1113 { 1114 pdev->params.ping_pong_dma = TRUE; 1115 } 1116 } 1117 else 1118 { 1119 pdev->params.ping_pong_dma = FALSE; 1120 } 1121 1122 /* Get the pre-emphasis. */ 1123 REG_RD_IND( 1124 pdev, 1125 pdev->hw_info.shmem_base + 1126 OFFSETOF(shmem_region_t, dev_info.port_hw_config.config), 1127 &pdev->params.serdes_pre_emphasis); 1128 pdev->params.serdes_pre_emphasis &= PORT_HW_CFG_SERDES_TXCTL3_MASK; 1129 1130 /* This should be fixed in A1. */ 1131 if(CHIP_ID(pdev) == CHIP_ID_5706_A0) 1132 { 1133 if(pdev->hw_info.bus_mode == BUS_MODE_PCIX && 1134 pdev->hw_info.bus_speed == BUS_SPEED_133_MHZ) 1135 { 1136 pdev->params.num_rchans = 1; 1137 } 1138 } 1139 1140 #if defined(DBG) && !defined(EXCLUDE_KQE_SUPPORT) 1141 pdev->params.con_kcqe_history_size = 256; 1142 pdev->params.con_kwqe_history_size = 256; 1143 #endif 1144 1145 if(CHIP_NUM(pdev) == CHIP_NUM_5708 || CHIP_NUM(pdev) == CHIP_NUM_5709) 1146 { 1147 if(lm_get_medium(pdev) == LM_MEDIUM_TYPE_FIBER) 1148 { 1149 pdev->params.phy_addr = 2; 1150 } 1151 } 1152 1153 if(CHIP_NUM(pdev) == CHIP_NUM_5709) 1154 { 1155 pdev->params.bin_mq_mode = TRUE; 1156 } 1157 1158 DbgBreakIf(NUM_RX_CHAIN != NUM_TX_CHAIN); 1159 1160 pdev->rx_info.num_rxq = NUM_RX_CHAIN; 1161 pdev->tx_info.num_txq = NUM_TX_CHAIN; 1162 pdev->tx_info.cu_idx = TX_CHAIN_IDX1; 1163 1164 /* see if remote phy is enabled. */ 1165 if(CHIP_REV(pdev) != CHIP_REV_IKOS) 1166 { 1167 REG_RD_IND( 1168 pdev, 1169 pdev->hw_info.shmem_base + 1170 OFFSETOF(shmem_region_t, 1171 dev_info.port_feature_config.config), 1172 &val); 1173 if(val & PORT_FEATURE_RPHY_ENABLED) 1174 { 1175 pdev->params.enable_remote_phy = 1; 1176 } 1177 } 1178 1179 if (CHIP_NUM(pdev) == CHIP_NUM_5706 || 1180 CHIP_NUM(pdev) == CHIP_NUM_5708) 1181 { 1182 // Due to slower speed of RV2P in Teton, we need to limit max 1183 // number of BD per each end bit. Otherwise, Appscan in RV2P 1184 // would spend excessive time scanning for end bit. 1185 pdev->params.limit_l4_rx_bd_cnt = 110; 1186 } 1187 1188 /* Override the defaults with user configurations. */ 1189 lm_status = mm_get_user_config(pdev); 1190 if(lm_status != LM_STATUS_SUCCESS) 1191 { 1192 return lm_status; 1193 } 1194 1195 /* Make sure share memory is initialized by the firmware. If not 1196 * fail initialization. The check here is a little late as we 1197 * have already read some share memory info above. This is ok. */ 1198 REG_RD_IND( 1199 pdev, 1200 pdev->hw_info.shmem_base + 1201 OFFSETOF(shmem_region_t, dev_info.signature), 1202 &val); 1203 if((val & DEV_INFO_SIGNATURE_MASK) != DEV_INFO_SIGNATURE) 1204 { 1205 if(!(pdev->params.test_mode & TEST_MODE_IGNORE_SHMEM_SIGNATURE)) 1206 { 1207 DbgBreakMsg("Shmem signature not present.\n"); 1208 1209 return LM_STATUS_BAD_SIGNATURE; 1210 } 1211 1212 pdev->hw_info.mac_addr[0] = 0x00; 1213 pdev->hw_info.mac_addr[1] = 0x10; 1214 pdev->hw_info.mac_addr[2] = 0x18; 1215 pdev->hw_info.mac_addr[3] = 0xff; 1216 pdev->hw_info.mac_addr[4] = 0xff; 1217 pdev->hw_info.mac_addr[5] = 0xff; 1218 1219 pdev->hw_info.iscsi_mac_addr[0] = 0x00; 1220 pdev->hw_info.iscsi_mac_addr[1] = 0x10; 1221 pdev->hw_info.iscsi_mac_addr[2] = 0x18; 1222 pdev->hw_info.iscsi_mac_addr[3] = 0xff; 1223 pdev->hw_info.iscsi_mac_addr[4] = 0xff; 1224 pdev->hw_info.iscsi_mac_addr[5] = 0xfe; 1225 } 1226 1227 /* Make sure the parameter values are within range. */ 1228 param = param_list; 1229 while(param->offset) 1230 { 1231 if(param->min != 0 || param->max != 0) 1232 { 1233 if(PARAM_VAL(pdev, param) < param->min || 1234 PARAM_VAL(pdev, param) > param->max) 1235 { 1236 if(CHIP_REV(pdev) == CHIP_REV_FPGA || 1237 CHIP_REV(pdev) == CHIP_REV_IKOS) 1238 { 1239 SET_PARAM_VAL(pdev, param, param->fpga_ikos_default); 1240 } 1241 else 1242 { 1243 SET_PARAM_VAL(pdev, param, param->asic_default); 1244 } 1245 } 1246 } 1247 1248 param++; 1249 } 1250 1251 /* params.mtu read from the registry does not include the MAC header 1252 * size. We need to add the header here. */ 1253 /* 1254 * get_vbd_params does this aleady 1255 * pdev->params.mtu += ETHERNET_PACKET_HEADER_SIZE; 1256 */ 1257 1258 #ifndef EXCLUDE_KQE_SUPPORT 1259 /* The size of the kcq histroy. This is the number entries that will 1260 * not be over written by the chip. */ 1261 if(pdev->params.kcq_history_size > (LM_PAGE_SIZE/sizeof(kcqe_t)) * 1262 pdev->params.kcq_page_cnt - 1) 1263 { 1264 pdev->params.kcq_history_size = ((LM_PAGE_SIZE/sizeof(kcqe_t)) * 1265 pdev->params.kcq_page_cnt) / 2; 1266 } 1267 #endif 1268 1269 /* XXX: Exception for Xinan, need a permanent fix. */ 1270 if (CHIP_NUM(pdev) == CHIP_NUM_5709) 1271 { 1272 pdev->params.rcv_buffer_offset = 0; 1273 } 1274 1275 /* Check for a valid mac address. */ 1276 if((pdev->params.mac_addr[0] == 0 && 1277 pdev->params.mac_addr[1] == 0 && 1278 pdev->params.mac_addr[2] == 0 && 1279 pdev->params.mac_addr[3] == 0 && 1280 pdev->params.mac_addr[4] == 0 && 1281 pdev->params.mac_addr[5] == 0) || (pdev->params.mac_addr[0] & 1)) 1282 { 1283 DbgMessage(pdev, WARN, "invalid LAA.\n"); 1284 1285 pdev->params.mac_addr[0] = pdev->hw_info.mac_addr[0]; 1286 pdev->params.mac_addr[1] = pdev->hw_info.mac_addr[1]; 1287 pdev->params.mac_addr[2] = pdev->hw_info.mac_addr[2]; 1288 pdev->params.mac_addr[3] = pdev->hw_info.mac_addr[3]; 1289 pdev->params.mac_addr[4] = pdev->hw_info.mac_addr[4]; 1290 pdev->params.mac_addr[5] = pdev->hw_info.mac_addr[5]; 1291 } 1292 1293 /* There is a bug in HC that will cause it to stop updating the 1294 * status block. This has been shown on some system with L4 traffic 1295 * goinging. To workaround this, the trip points and interrupt trip 1296 * points must be the same and the statistics DMA must be disabled. */ 1297 if(CHIP_ID(pdev) == CHIP_ID_5706_A0) 1298 { 1299 pdev->params.tx_quick_cons_trip_int = pdev->params.tx_quick_cons_trip; 1300 pdev->params.tx_ticks_int = pdev->params.tx_ticks; 1301 pdev->params.rx_quick_cons_trip_int = pdev->params.rx_quick_cons_trip; 1302 pdev->params.rx_ticks_int = pdev->params.rx_ticks; 1303 pdev->params.comp_prod_trip_int = pdev->params.comp_prod_trip; 1304 pdev->params.com_ticks_int = pdev->params.com_ticks; 1305 pdev->params.cmd_ticks_int = pdev->params.cmd_ticks; 1306 pdev->params.stats_ticks = 0; 1307 } 1308 1309 /* enable_syn_rcvd will direct all tcp segments with syn bit to rxq 1. */ 1310 if(pdev->params.enable_syn_rcvq && 1311 NUM_RX_CHAIN > 1 && 1312 pdev->params.l2_rx_desc_cnt[1] == 0) 1313 { 1314 pdev->params.l2_rx_desc_cnt[1] = 60; 1315 } 1316 1317 /* Timer mode is broken is 5706_A0 and 5706_A1. */ 1318 if(CHIP_ID(pdev) == CHIP_ID_5706_A0 || CHIP_ID(pdev) == CHIP_ID_5706_A1) 1319 { 1320 pdev->params.hc_timer_mode = HC_COLLECT_MODE; 1321 } 1322 1323 /* Get the current fw_wr_seq. */ 1324 REG_RD_IND( 1325 pdev, 1326 pdev->hw_info.shmem_base + OFFSETOF(shmem_region_t, drv_fw_mb.fw_mb), 1327 &val); 1328 pdev->vars.fw_wr_seq = val & DRV_MSG_SEQ; 1329 1330 /* see if firmware is remote phy capable. */ 1331 if(pdev->params.enable_remote_phy) 1332 { 1333 REG_RD_IND( 1334 pdev, 1335 pdev->hw_info.shmem_base + 1336 OFFSETOF(shmem_region_t, drv_fw_cap_mb.fw_cap_mb), 1337 &val); 1338 if((val & CAPABILITY_SIGNATURE_MASK) != FW_CAP_SIGNATURE || 1339 (val & FW_CAP_REMOTE_PHY_CAPABLE) == 0) 1340 { 1341 pdev->params.enable_remote_phy = 0; 1342 } 1343 } 1344 1345 return LM_STATUS_SUCCESS; 1346 } /* lm_get_dev_info */ 1347 1348 1349 1350 #ifndef EXCLUDE_KQE_SUPPORT 1351 /******************************************************************************* 1352 * Description: 1353 * 1354 * Return: 1355 ******************************************************************************/ 1356 STATIC lm_status_t 1357 init_kwq_resc( 1358 lm_device_t *pdev) 1359 { 1360 u32_t mem_size; 1361 1362 if(pdev->params.kwq_page_cnt == 0) 1363 { 1364 return LM_STATUS_SUCCESS; 1365 } 1366 1367 /* Allocate memory for the page table which does not need to be 1368 * page aligned. However the size must be multiple of page size. 1369 * 1370 * When initialized, the page table will point to the pages 1371 * used for the kernel work queue. */ 1372 mem_size = pdev->params.kwq_page_cnt * sizeof(lm_address_t); 1373 mem_size = (mem_size + LM_PAGE_MASK) & ~LM_PAGE_MASK; 1374 1375 pdev->kq_info.kwq_pgtbl_virt = mm_alloc_phys_mem( 1376 pdev, 1377 mem_size, 1378 &pdev->kq_info.kwq_pgtbl_phy, 1379 PHYS_MEM_TYPE_NONCACHED, 1380 NULL); 1381 if(pdev->kq_info.kwq_pgtbl_virt == NULL) 1382 { 1383 return LM_STATUS_RESOURCE; 1384 } 1385 1386 DbgBreakIf(pdev->kq_info.kwq_pgtbl_phy.as_u32.low & CACHE_LINE_SIZE_MASK); 1387 1388 /* Allocate memory for the kernel work queue. Here we allocate 1389 * a physically continuous block of memory and then initialize the 1390 * page table to pointer to the pages in this block. 1391 * 1392 * The kernel work queue is used by the driver similiar to a 1393 * circular ring. 1394 * 1395 * The memory block must be page aligned. */ 1396 mem_size = LM_PAGE_SIZE * pdev->params.kwq_page_cnt; 1397 pdev->kq_info.kwq_virt = (kwqe_t *) mm_alloc_phys_mem( 1398 pdev, 1399 mem_size, 1400 &pdev->kq_info.kwq_phy, 1401 PHYS_MEM_TYPE_NONCACHED, 1402 NULL); 1403 if(pdev->kq_info.kwq_virt == NULL) 1404 { 1405 return LM_STATUS_RESOURCE; 1406 } 1407 1408 DbgBreakIf(pdev->kq_info.kwq_phy.as_u32.low & CACHE_LINE_SIZE_MASK); 1409 DbgBreakIf(((u8_t *) pdev->kq_info.kwq_virt - (u8_t *) 0) & LM_PAGE_MASK); 1410 1411 return LM_STATUS_SUCCESS; 1412 } /* init_kwq_resc */ 1413 1414 1415 1416 /******************************************************************************* 1417 * Description: 1418 * 1419 * Return: 1420 ******************************************************************************/ 1421 STATIC lm_status_t 1422 init_kcq_resc( 1423 lm_device_t *pdev) 1424 { 1425 1426 u32_t mem_size; 1427 1428 if(pdev->params.kcq_page_cnt == 0) 1429 { 1430 return LM_STATUS_SUCCESS; 1431 } 1432 1433 /* Allocate memory for the page table which does not need to be 1434 * page aligned. However the size must be multiple of page size. 1435 * 1436 * When initialized, the page table will point to the pages 1437 * used for the kernel completion queue. */ 1438 mem_size = pdev->params.kcq_page_cnt * sizeof(lm_address_t); 1439 mem_size = (mem_size + LM_PAGE_MASK) & ~LM_PAGE_MASK; 1440 1441 pdev->kq_info.kcq_pgtbl_virt = mm_alloc_phys_mem( 1442 pdev, 1443 mem_size, 1444 &pdev->kq_info.kcq_pgtbl_phy, 1445 PHYS_MEM_TYPE_NONCACHED, 1446 NULL); 1447 if(pdev->kq_info.kcq_pgtbl_virt == NULL) 1448 { 1449 return LM_STATUS_RESOURCE; 1450 } 1451 1452 DbgBreakIf(pdev->kq_info.kcq_pgtbl_phy.as_u32.low & CACHE_LINE_SIZE_MASK); 1453 1454 /* Allocate memory for the kernel completion queue. Here we allocate 1455 * a physically continuous block of memory and then initialize the 1456 * page table to pointer to the pages in this block. 1457 * 1458 * The kernel completion queue is used by the driver similiar to a 1459 * circular ring. 1460 * 1461 * The memory block must be page aligned. */ 1462 mem_size = LM_PAGE_SIZE * pdev->params.kcq_page_cnt; 1463 1464 pdev->kq_info.kcq_virt = (kcqe_t *) mm_alloc_phys_mem( 1465 pdev, 1466 mem_size, 1467 &pdev->kq_info.kcq_phy, 1468 PHYS_MEM_TYPE_NONCACHED, 1469 NULL); 1470 if(pdev->kq_info.kcq_virt == NULL) 1471 { 1472 return LM_STATUS_RESOURCE; 1473 } 1474 1475 DbgBreakIf(pdev->kq_info.kcq_phy.as_u32.low & CACHE_LINE_SIZE_MASK); 1476 DbgBreakIf(((u8_t *) pdev->kq_info.kcq_virt - (u8_t *) 0) & LM_PAGE_MASK); 1477 1478 return LM_STATUS_SUCCESS; 1479 } /* init_kcq_resc */ 1480 #endif /* EXCLUDE_KQE_SUPPORT */ 1481 1482 1483 1484 #if INCLUDE_OFLD_SUPPORT 1485 /******************************************************************************* 1486 * Description: 1487 * 1488 * Return: 1489 ******************************************************************************/ 1490 STATIC lm_status_t 1491 init_ofld_resc( 1492 lm_device_t *pdev) 1493 { 1494 lm_offload_info_t *ofld; 1495 u32_t mem_size; 1496 u32_t idx; 1497 1498 ofld = &pdev->ofld; 1499 ofld->pdev = pdev; 1500 ofld->pg_cid_hnd_info.max_pending_pg_oflds = 16; 1501 ofld->pg_cid_hnd_info.pending_pg_ofld_cnt = 0; 1502 1503 s_list_init(&ofld->active_req_list, NULL, NULL, 0); 1504 s_list_init(&ofld->upload_req_list, NULL, NULL, 0); 1505 1506 for(idx = 0; idx < STATE_BLOCK_CNT; idx++) 1507 { 1508 d_list_init(&ofld->state_blks[idx].tcp_list, NULL, NULL, 0); 1509 d_list_init(&ofld->state_blks[idx].path_list, NULL, NULL, 0); 1510 d_list_init(&ofld->state_blks[idx].neigh_list, NULL, NULL, 0); 1511 1512 ofld->state_blks[idx].max_conn = 0xffffffff; 1513 1514 ofld->state_blks[idx].state_block_idx = idx; 1515 ofld->state_blks[idx].ofld = ofld; 1516 1517 ofld->state_blks[idx].params.ticks_per_second = 100; 1518 ofld->state_blks[idx].params.ack_frequency = 2; 1519 ofld->state_blks[idx].params.delayed_ack_ticks = 20; 1520 ofld->state_blks[idx].params.max_retx = 10; 1521 ofld->state_blks[idx].params.doubt_reachability_retx = 8; 1522 ofld->state_blks[idx].params.sws_prevention_ticks = 10; 1523 ofld->state_blks[idx].params.dup_ack_threshold = 3; 1524 ofld->state_blks[idx].params.push_ticks = 20; 1525 ofld->state_blks[idx].params.nce_stale_ticks = 20; 1526 ofld->state_blks[idx].params.starting_ip_id = 0x8000; 1527 } 1528 1529 /* Allocate memory for the generic buffer chain. */ 1530 mem_size = LM_PAGE_SIZE * pdev->params.gen_bd_page_cnt; 1531 ofld->gen_chain.bd_chain_virt = (rx_bd_t *) mm_alloc_phys_mem( 1532 pdev, 1533 mem_size, 1534 &ofld->gen_chain.bd_chain_phy, 1535 PHYS_MEM_TYPE_UNSPECIFIED, 1536 NULL); 1537 if(ofld->gen_chain.bd_chain_virt == NULL) 1538 { 1539 return LM_STATUS_RESOURCE; 1540 } 1541 1542 DbgBreakIf(ofld->gen_chain.bd_chain_phy.as_u32.low & CACHE_LINE_SIZE_MASK); 1543 1544 ofld->gen_chain.cid_addr = GET_CID_ADDR(GEN_CHAIN_CID); 1545 1546 s_list_init(&ofld->gen_chain.block_list, NULL, NULL, 0); 1547 s_list_init(&ofld->gen_chain.free_gen_buf_list, NULL, NULL, 0); 1548 s_list_init(&ofld->gen_chain.active_gen_buf_list, NULL, NULL, 0); 1549 1550 /* Allocate memory for the hcopy chain. */ 1551 if(pdev->params.hcopy_desc_cnt) 1552 { 1553 mem_size = LM_PAGE_SIZE * pdev->params.hcopy_bd_page_cnt; 1554 ofld->hcopy_chain.bd_chain_virt =(tx_bd_t *) mm_alloc_phys_mem( 1555 pdev, 1556 mem_size, 1557 &ofld->hcopy_chain.bd_chain_phy, 1558 PHYS_MEM_TYPE_UNSPECIFIED, 1559 NULL); 1560 if(ofld->hcopy_chain.bd_chain_virt == NULL) 1561 { 1562 return LM_STATUS_RESOURCE; 1563 } 1564 1565 DbgBreakIf(ofld->hcopy_chain.bd_chain_phy.as_u32.low & 1566 CACHE_LINE_SIZE_MASK); 1567 1568 ofld->hcopy_chain.cid_addr = GET_CID_ADDR(HCOPY_CID); 1569 ofld->hcopy_chain.hw_con_idx_ptr = 1570 &pdev->vars.status_virt->deflt.status_rx_quick_consumer_index15; 1571 1572 s_list_init(&ofld->hcopy_chain.pending_descq, NULL, NULL, 0); 1573 s_list_init(&ofld->hcopy_chain.active_descq, NULL, NULL, 0); 1574 } 1575 1576 ofld->cid_to_state = (lm_state_header_t **) mm_alloc_mem( 1577 pdev, 1578 sizeof(lm_state_header_t *) * MAX_CID, 1579 NULL); 1580 if(ofld->cid_to_state == NULL) 1581 { 1582 return LM_STATUS_RESOURCE; 1583 } 1584 1585 return LM_STATUS_SUCCESS; 1586 } /* init_ofld_resc */ 1587 #endif /* INCLUDE_OFLD_SUPPORT */ 1588 1589 1590 1591 /******************************************************************************* 1592 * Description: 1593 * 1594 * Return: 1595 ******************************************************************************/ 1596 STATIC volatile u16_t * 1597 sblk_tx_con_idx_ptr( 1598 lm_device_t *pdev, 1599 lm_tx_chain_t *txq) 1600 { 1601 volatile status_blk_combined_t *sblk; 1602 volatile u16_t *idx_ptr; 1603 1604 sblk = pdev->vars.status_virt; 1605 1606 if(CHIP_NUM(pdev) == CHIP_NUM_5706 || CHIP_NUM(pdev) == CHIP_NUM_5708) 1607 { 1608 switch(txq->idx) 1609 { 1610 case TX_CHAIN_IDX0: 1611 idx_ptr = &sblk->deflt.status_tx_quick_consumer_index0; 1612 break; 1613 1614 case TX_CHAIN_IDX1: 1615 idx_ptr = &sblk->deflt.status_tx_quick_consumer_index1; 1616 break; 1617 1618 case TX_CHAIN_IDX2: 1619 idx_ptr = &sblk->deflt.status_tx_quick_consumer_index2; 1620 break; 1621 1622 case TX_CHAIN_IDX3: 1623 idx_ptr = &sblk->deflt.status_tx_quick_consumer_index3; 1624 break; 1625 1626 default: 1627 idx_ptr = NULL; 1628 1629 DbgBreakIf(txq->idx != pdev->tx_info.cu_idx); 1630 1631 if(txq->idx == pdev->tx_info.cu_idx) 1632 { 1633 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index14; 1634 } 1635 break; 1636 } 1637 } 1638 else 1639 { 1640 switch(txq->idx) 1641 { 1642 case TX_CHAIN_IDX0: 1643 idx_ptr = &sblk->deflt.status_tx_quick_consumer_index0; 1644 break; 1645 1646 case TX_CHAIN_IDX1: 1647 idx_ptr = &sblk->deflt.status_tx_quick_consumer_index1; 1648 break; 1649 1650 case TX_CHAIN_IDX2: 1651 idx_ptr = &sblk->deflt.status_tx_quick_consumer_index2; 1652 break; 1653 1654 case TX_CHAIN_IDX3: 1655 idx_ptr = &sblk->deflt.status_tx_quick_consumer_index3; 1656 break; 1657 1658 case TX_CHAIN_IDX4: 1659 idx_ptr = &sblk->proc[0].status_pcpu_tx_quick_consumer_index; 1660 break; 1661 1662 case TX_CHAIN_IDX5: 1663 idx_ptr = &sblk->proc[1].status_pcpu_tx_quick_consumer_index; 1664 break; 1665 1666 case TX_CHAIN_IDX6: 1667 idx_ptr = &sblk->proc[2].status_pcpu_tx_quick_consumer_index; 1668 break; 1669 1670 case TX_CHAIN_IDX7: 1671 idx_ptr = &sblk->proc[3].status_pcpu_tx_quick_consumer_index; 1672 break; 1673 1674 case TX_CHAIN_IDX8: 1675 idx_ptr = &sblk->proc[4].status_pcpu_tx_quick_consumer_index; 1676 break; 1677 1678 case TX_CHAIN_IDX9: 1679 idx_ptr = &sblk->proc[5].status_pcpu_tx_quick_consumer_index; 1680 break; 1681 1682 case TX_CHAIN_IDX10: 1683 idx_ptr = &sblk->proc[6].status_pcpu_tx_quick_consumer_index; 1684 break; 1685 1686 case TX_CHAIN_IDX11: 1687 idx_ptr = &sblk->proc[7].status_pcpu_tx_quick_consumer_index; 1688 break; 1689 1690 default: 1691 DbgBreakMsg("invalid xinan tx index.\n"); 1692 idx_ptr = NULL; 1693 break; 1694 } 1695 } 1696 1697 return idx_ptr; 1698 } /* sblk_tx_con_idx_ptr */ 1699 1700 1701 1702 /******************************************************************************* 1703 * Description: 1704 * 1705 * Return: 1706 ******************************************************************************/ 1707 STATIC lm_status_t 1708 init_l2tx_resc( 1709 lm_device_t *pdev) 1710 { 1711 lm_tx_chain_t *txq; 1712 u32_t bd_page_cnt; 1713 u32_t mem_size; 1714 u32_t idx; 1715 u32_t num_tx_chains; 1716 1717 #if defined(LM_NON_LEGACY_MODE_SUPPORT) 1718 num_tx_chains = MAX_TX_CHAIN; 1719 if(CHIP_NUM(pdev) == CHIP_NUM_5706 || CHIP_NUM(pdev) == CHIP_NUM_5708) 1720 { 1721 num_tx_chains = pdev->tx_info.num_txq; 1722 } 1723 #else 1724 DbgBreakIf(pdev->tx_info.num_txq > MAX_TX_CHAIN); 1725 for(idx = pdev->tx_info.num_txq; idx < MAX_TX_CHAIN; idx++) 1726 { 1727 pdev->params.l2_tx_bd_page_cnt[idx] = 0; 1728 } 1729 num_tx_chains = pdev->tx_info.num_txq; 1730 #endif 1731 for(idx = 0; idx < num_tx_chains; idx++) 1732 { 1733 txq = &pdev->tx_info.chain[idx]; 1734 txq->idx = idx; 1735 txq->cid_addr = GET_CID_ADDR(L2TX_CID_BASE + 2 * txq->idx); 1736 1737 s_list_init(&txq->active_descq, NULL, NULL, 0); 1738 1739 if(CHIP_NUM(pdev) == CHIP_NUM_5706 || CHIP_NUM(pdev) == CHIP_NUM_5708) 1740 { 1741 DbgBreakIf(idx > 4); 1742 1743 if(txq->idx == pdev->tx_info.cu_idx && txq->idx != TX_CHAIN_IDX1) 1744 { 1745 DbgBreakIf(idx != 4); 1746 txq->cid_addr = GET_CID_ADDR(30); 1747 } 1748 } 1749 else if(txq->idx >= 4) 1750 { 1751 DbgBreakIf(idx > 11); 1752 1753 /* Xinan has to use tx1 for catchup because catchup2 uses 1754 * status_rx_quick_consumer_index14 for completion. This 1755 * status block index is not available on Xinan. */ 1756 DbgBreakIf(pdev->tx_info.cu_idx != TX_CHAIN_IDX1); 1757 1758 if(txq->idx >= 4) 1759 { 1760 txq->cid_addr = GET_CID_ADDR(L2TX_TSS_CID_BASE + txq->idx - 4); 1761 } 1762 } 1763 1764 bd_page_cnt = pdev->params.l2_tx_bd_page_cnt[txq->idx]; 1765 if(bd_page_cnt) 1766 { 1767 mem_size = LM_PAGE_SIZE * bd_page_cnt; 1768 1769 txq->bd_chain_virt = (tx_bd_t *) mm_alloc_phys_mem( 1770 pdev, 1771 mem_size, 1772 &txq->bd_chain_phy, 1773 PHYS_MEM_TYPE_NONCACHED, 1774 NULL); 1775 if(txq->bd_chain_virt == NULL) 1776 { 1777 return LM_STATUS_RESOURCE; 1778 } 1779 1780 DbgBreakIf(txq->bd_chain_phy.as_u32.low & CACHE_LINE_SIZE_MASK); 1781 } 1782 1783 txq->hw_con_idx_ptr = sblk_tx_con_idx_ptr(pdev, txq); 1784 } 1785 1786 return LM_STATUS_SUCCESS; 1787 } /* init_l2tx_resc */ 1788 1789 1790 1791 /******************************************************************************* 1792 * Description: 1793 * 1794 * Return: 1795 ******************************************************************************/ 1796 STATIC volatile u16_t * 1797 sblk_rx_con_idx_ptr( 1798 lm_device_t *pdev, 1799 lm_rx_chain_t *rxq) 1800 { 1801 volatile status_blk_combined_t *sblk; 1802 volatile u16_t *idx_ptr; 1803 1804 sblk = pdev->vars.status_virt; 1805 1806 if(CHIP_NUM(pdev) == CHIP_NUM_5706 || CHIP_NUM(pdev) == CHIP_NUM_5708) 1807 { 1808 switch(rxq->idx) 1809 { 1810 case RX_CHAIN_IDX0: 1811 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index0; 1812 break; 1813 1814 case RX_CHAIN_IDX1: 1815 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index1; 1816 break; 1817 1818 case RX_CHAIN_IDX2: 1819 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index2; 1820 break; 1821 1822 case RX_CHAIN_IDX3: 1823 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index3; 1824 break; 1825 1826 case RX_CHAIN_IDX4: 1827 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index4; 1828 break; 1829 1830 case RX_CHAIN_IDX5: 1831 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index5; 1832 break; 1833 1834 case RX_CHAIN_IDX6: 1835 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index6; 1836 break; 1837 1838 case RX_CHAIN_IDX7: 1839 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index7; 1840 break; 1841 1842 case RX_CHAIN_IDX8: 1843 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index8; 1844 break; 1845 1846 case RX_CHAIN_IDX9: 1847 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index9; 1848 break; 1849 1850 case RX_CHAIN_IDX10: 1851 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index10; 1852 break; 1853 1854 case RX_CHAIN_IDX11: 1855 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index11; 1856 break; 1857 1858 case RX_CHAIN_IDX12: 1859 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index12; 1860 break; 1861 1862 case RX_CHAIN_IDX13: 1863 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index13; 1864 break; 1865 1866 case RX_CHAIN_IDX14: 1867 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index14; 1868 break; 1869 1870 case RX_CHAIN_IDX15: 1871 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index15; 1872 break; 1873 1874 default: 1875 DbgBreakMsg("invalid teton rx index.\n"); 1876 idx_ptr = NULL; 1877 break; 1878 } 1879 } 1880 else 1881 { 1882 switch(rxq->idx) 1883 { 1884 case RX_CHAIN_IDX0: 1885 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index0; 1886 break; 1887 1888 case RX_CHAIN_IDX1: 1889 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index1; 1890 break; 1891 1892 case RX_CHAIN_IDX2: 1893 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index2; 1894 break; 1895 1896 case RX_CHAIN_IDX3: 1897 idx_ptr = &sblk->deflt.status_rx_quick_consumer_index3; 1898 break; 1899 1900 case RX_CHAIN_IDX4: 1901 idx_ptr = &sblk->proc[0].status_pcpu_rx_quick_consumer_index; 1902 break; 1903 1904 case RX_CHAIN_IDX5: 1905 idx_ptr = &sblk->proc[1].status_pcpu_rx_quick_consumer_index; 1906 break; 1907 1908 case RX_CHAIN_IDX6: 1909 idx_ptr = &sblk->proc[2].status_pcpu_rx_quick_consumer_index; 1910 break; 1911 1912 case RX_CHAIN_IDX7: 1913 idx_ptr = &sblk->proc[3].status_pcpu_rx_quick_consumer_index; 1914 break; 1915 1916 case RX_CHAIN_IDX8: 1917 idx_ptr = &sblk->proc[4].status_pcpu_rx_quick_consumer_index; 1918 break; 1919 1920 case RX_CHAIN_IDX9: 1921 idx_ptr = &sblk->proc[5].status_pcpu_rx_quick_consumer_index; 1922 break; 1923 1924 case RX_CHAIN_IDX10: 1925 idx_ptr = &sblk->proc[6].status_pcpu_rx_quick_consumer_index; 1926 break; 1927 1928 case RX_CHAIN_IDX11: 1929 idx_ptr = &sblk->proc[7].status_pcpu_rx_quick_consumer_index; 1930 break; 1931 1932 default: 1933 DbgBreakMsg("invalid xinan rx index.\n"); 1934 idx_ptr = NULL; 1935 break; 1936 } 1937 } 1938 1939 return idx_ptr; 1940 } /* sblk_rx_con_idx_ptr */ 1941 1942 1943 1944 /******************************************************************************* 1945 * Description: 1946 * 1947 * Return: 1948 ******************************************************************************/ 1949 STATIC lm_status_t 1950 alloc_l2rx_desc( 1951 lm_device_t *pdev, 1952 lm_rx_chain_t *rxq) 1953 { 1954 u32_t bd_page_cnt; 1955 lm_packet_t *pkt; 1956 u32_t desc_size; 1957 u32_t desc_cnt; 1958 u8_t *mem_virt; 1959 u32_t mem_size; 1960 u32_t idx; 1961 1962 bd_page_cnt = pdev->params.l2_rx_bd_page_cnt[rxq->idx]; 1963 desc_cnt = pdev->params.l2_rx_desc_cnt[rxq->idx]; 1964 1965 if(bd_page_cnt == 0 || desc_cnt == 0) 1966 { 1967 pdev->params.l2_rx_bd_page_cnt[rxq->idx] = 0; 1968 pdev->params.l2_rx_desc_cnt[rxq->idx] = 0; 1969 1970 return LM_STATUS_SUCCESS; 1971 } 1972 1973 mem_size = LM_PAGE_SIZE * bd_page_cnt; 1974 1975 rxq->bd_chain_virt = (rx_bd_t *) mm_alloc_phys_mem( 1976 pdev, 1977 mem_size, 1978 &rxq->bd_chain_phy, 1979 PHYS_MEM_TYPE_NONCACHED, 1980 NULL); 1981 if(rxq->bd_chain_virt == NULL) 1982 { 1983 return LM_STATUS_RESOURCE; 1984 } 1985 1986 DbgBreakIf(rxq->bd_chain_phy.as_u32.low & CACHE_LINE_SIZE_MASK); 1987 1988 #ifndef LM_NON_LEGACY_MODE_SUPPORT 1989 desc_size = mm_desc_size(pdev, DESC_TYPE_L2RX_PACKET) + SIZEOF_SIG; 1990 mem_size = desc_size * desc_cnt; 1991 1992 mem_virt = (u8_t *) mm_alloc_mem(pdev, mem_size, NULL); 1993 if(mem_virt == NULL) 1994 { 1995 return LM_STATUS_RESOURCE; 1996 } 1997 1998 for(idx = 0; idx < desc_cnt; idx++) 1999 { 2000 pkt = (lm_packet_t *) (mem_virt + SIZEOF_SIG); 2001 mem_virt += desc_size; 2002 mem_size -= desc_size; 2003 2004 SIG(pkt) = L2PACKET_RX_SIG; 2005 // full packet needs to hold mtu + 4-byte CRC32 2006 pkt->u1.rx.buf_size = pdev->params.mtu + 4; 2007 pkt->u1.rx.buf_size += L2RX_FRAME_HDR_LEN; 2008 pkt->u1.rx.buf_size += pdev->params.rcv_buffer_offset; 2009 pkt->u1.rx.buf_size += CACHE_LINE_SIZE_MASK + 1; 2010 pkt->u1.rx.buf_size &= ~CACHE_LINE_SIZE_MASK; 2011 2012 s_list_push_tail(&rxq->free_descq, &pkt->link); 2013 } 2014 2015 DbgBreakIf(mem_size); 2016 DbgBreakIf(s_list_entry_cnt(&rxq->free_descq) != desc_cnt); 2017 #endif 2018 return LM_STATUS_SUCCESS; 2019 } /* alloc_l2rx_desc */ 2020 2021 2022 2023 /******************************************************************************* 2024 * Description: 2025 * 2026 * Return: 2027 ******************************************************************************/ 2028 STATIC lm_status_t 2029 init_l2rx_resc( 2030 lm_device_t *pdev) 2031 { 2032 lm_status_t lm_status; 2033 lm_rx_chain_t *rxq; 2034 u32_t idx; 2035 2036 #ifndef LM_NON_LEGACY_MODE_SUPPORT 2037 DbgBreakIf(pdev->rx_info.num_rxq > MAX_RX_CHAIN); 2038 2039 for(idx = pdev->rx_info.num_rxq; idx < MAX_RX_CHAIN; idx++) 2040 { 2041 pdev->params.l2_rx_desc_cnt[idx] = 0; 2042 pdev->params.l2_rx_bd_page_cnt[idx] = 0; 2043 } 2044 #endif 2045 for(idx = 0; idx < pdev->rx_info.num_rxq ; idx++) 2046 { 2047 rxq = &pdev->rx_info.chain[idx]; 2048 rxq->idx = idx; 2049 rxq->cid_addr = GET_CID_ADDR(L2RX_CID_BASE + rxq->idx); 2050 2051 s_list_init(&rxq->free_descq, NULL, NULL, 0); 2052 s_list_init(&rxq->active_descq, NULL, NULL, 0); 2053 2054 lm_status = alloc_l2rx_desc(pdev, rxq); 2055 if(lm_status != LM_STATUS_SUCCESS) 2056 { 2057 return lm_status; 2058 } 2059 2060 rxq->hw_con_idx_ptr = sblk_rx_con_idx_ptr(pdev, rxq); 2061 } 2062 2063 return LM_STATUS_SUCCESS; 2064 } /* init_l2rx_resc */ 2065 2066 2067 2068 /******************************************************************************* 2069 * Description: 2070 * 2071 * Return: 2072 ******************************************************************************/ 2073 STATIC lm_status_t 2074 init_context_resc_5709( 2075 lm_device_t *pdev) 2076 { 2077 phy_mem_block_t *ctx_mem; 2078 u32_t page_align_delta; 2079 lm_address_t mem_phy; 2080 u32_t ctx_in_mblk; 2081 u32_t mem_size; 2082 u8_t *mem_virt; 2083 u32_t ctx_cnt; 2084 2085 DbgBreakIf(CHIP_NUM(pdev) != CHIP_NUM_5709); 2086 DbgBreakIf(CTX_MBLK_SIZE & LM_PAGE_MASK); 2087 DbgBreakIf(MAX_CTX > 16 * 1024); 2088 DbgBreakIf(MAX_CTX * ONE_CTX_SIZE / CTX_MBLK_SIZE != NUM_CTX_MBLKS); 2089 DbgBreakIf((MAX_CTX * ONE_CTX_SIZE) % CTX_MBLK_SIZE); 2090 2091 ctx_mem = &pdev->vars.ctx_mem[0]; 2092 ctx_cnt = 0; 2093 2094 while(ctx_cnt < MAX_CTX) 2095 { 2096 ctx_in_mblk = CTX_MBLK_SIZE / ONE_CTX_SIZE; 2097 if(ctx_cnt + ctx_in_mblk > MAX_CTX) 2098 { 2099 ctx_in_mblk = MAX_CTX - ctx_cnt; 2100 } 2101 2102 mem_size = ctx_in_mblk * ONE_CTX_SIZE; 2103 2104 mem_virt = (u8_t *) mm_alloc_phys_mem( 2105 pdev, 2106 mem_size + LM_PAGE_MASK, 2107 &mem_phy, 2108 PHYS_MEM_TYPE_NONCACHED, 2109 NULL); 2110 if(mem_virt == NULL) 2111 { 2112 return LM_STATUS_RESOURCE; 2113 } 2114 2115 page_align_delta = mem_phy.as_u32.low & LM_PAGE_MASK; 2116 if(page_align_delta) 2117 { 2118 page_align_delta = LM_PAGE_SIZE - page_align_delta; 2119 } 2120 2121 mem_virt += page_align_delta; 2122 LM_INC64(&mem_phy, page_align_delta); 2123 2124 ctx_mem->start_phy = mem_phy; 2125 ctx_mem->start = mem_virt; 2126 ctx_mem->size = mem_size; 2127 ctx_mem++; 2128 2129 ctx_cnt += mem_size / ONE_CTX_SIZE; 2130 } 2131 2132 return LM_STATUS_SUCCESS; 2133 } /* init_context_resc_5709 */ 2134 2135 2136 2137 /******************************************************************************* 2138 * Description: 2139 * 2140 * Return: 2141 ******************************************************************************/ 2142 lm_status_t 2143 lm_init_resc( 2144 lm_device_t *pdev) 2145 { 2146 lm_status_t lm_status; 2147 lm_address_t mem_phy; 2148 u8_t *mem_virt; 2149 u32_t mem_size; 2150 2151 #ifndef EXCLUDE_KQE_SUPPORT 2152 lm_status = init_kwq_resc(pdev); 2153 if(lm_status != LM_STATUS_SUCCESS) 2154 { 2155 return lm_status; 2156 } 2157 2158 lm_status = init_kcq_resc(pdev); 2159 if(lm_status != LM_STATUS_SUCCESS) 2160 { 2161 return lm_status; 2162 } 2163 #endif 2164 2165 #if INCLUDE_OFLD_SUPPORT 2166 lm_status = init_ofld_resc(pdev); 2167 if(lm_status != LM_STATUS_SUCCESS) 2168 { 2169 return lm_status; 2170 } 2171 #endif 2172 2173 DbgBreakIf(sizeof(status_blk_combined_t) > STATUS_BLOCK_BUFFER_SIZE); 2174 DbgBreakIf(sizeof(statistics_block_t) > CHIP_STATS_BUFFER_SIZE); 2175 2176 mem_size = STATUS_BLOCK_BUFFER_SIZE + 2177 #ifndef EXCLUDE_RSS_SUPPORT 2178 RSS_INDIRECTION_TABLE_SIZE + 2179 RSS_LOOKUP_TABLE_WA + 2180 #endif 2181 CHIP_STATS_BUFFER_SIZE; 2182 2183 mem_virt = mm_alloc_phys_mem( 2184 pdev, 2185 mem_size, 2186 &mem_phy, 2187 PHYS_MEM_TYPE_NONCACHED, 2188 NULL); 2189 if(mem_virt == NULL) 2190 { 2191 return LM_STATUS_RESOURCE; 2192 } 2193 2194 DbgBreakIf(mem_phy.as_u32.low & CACHE_LINE_SIZE_MASK); 2195 2196 pdev->vars.status_virt = (status_blk_combined_t *) mem_virt; 2197 pdev->vars.status_phy = mem_phy; 2198 mem_virt += STATUS_BLOCK_BUFFER_SIZE; 2199 LM_INC64(&mem_phy, STATUS_BLOCK_BUFFER_SIZE); 2200 2201 pdev->vars.stats_virt = (statistics_block_t *) mem_virt; 2202 pdev->vars.stats_phy = mem_phy; 2203 mem_virt += CHIP_STATS_BUFFER_SIZE; 2204 LM_INC64(&mem_phy, CHIP_STATS_BUFFER_SIZE); 2205 2206 #ifndef EXCLUDE_RSS_SUPPORT 2207 pdev->rx_info.rss_ind_table_virt = mem_virt; 2208 pdev->rx_info.rss_ind_table_phy = mem_phy; 2209 #endif 2210 2211 if(CHIP_NUM(pdev) == CHIP_NUM_5709) 2212 { 2213 lm_status = init_context_resc_5709(pdev); 2214 if(lm_status != LM_STATUS_SUCCESS) 2215 { 2216 return lm_status; 2217 } 2218 } 2219 2220 lm_status = init_l2tx_resc(pdev); 2221 if(lm_status != LM_STATUS_SUCCESS) 2222 { 2223 return lm_status; 2224 } 2225 2226 lm_status = init_l2rx_resc(pdev); 2227 if(lm_status != LM_STATUS_SUCCESS) 2228 { 2229 return lm_status; 2230 } 2231 2232 lm_clear_nwuf(pdev); 2233 2234 return LM_STATUS_SUCCESS; 2235 } /* lm_init_resc */ 2236 2237 2238 2239 /******************************************************************************* 2240 * Description: 2241 * 2242 * Return: 2243 ******************************************************************************/ 2244 STATIC u32_t 2245 compute_crc32( 2246 u8_t *buf, 2247 u32_t buf_size) 2248 { 2249 u32_t reg; 2250 u32_t tmp; 2251 u32_t j; 2252 u32_t k; 2253 2254 reg = 0xffffffff; 2255 2256 for(j = 0; j < buf_size; j++) 2257 { 2258 reg ^= buf[j]; 2259 2260 for(k = 0; k < 8; k++) 2261 { 2262 tmp = reg & 0x01; 2263 2264 reg >>= 1; 2265 2266 if(tmp) 2267 { 2268 reg ^= 0xedb88320; 2269 } 2270 } 2271 } 2272 2273 return ~reg; 2274 } /* compute_crc32 */ 2275 2276 2277 2278 #define NUM_MC_HASH_REGISTERS 8 2279 /******************************************************************************* 2280 * Description: 2281 * 2282 * Return: 2283 ******************************************************************************/ 2284 STATIC void 2285 set_mc_hash_reg( 2286 lm_device_t *pdev, 2287 lm_mc_table_t *mc_table) 2288 { 2289 u32_t hash_reg[NUM_MC_HASH_REGISTERS]; 2290 u32_t reg_idx; 2291 u32_t bit_pos; 2292 u32_t idx; 2293 u32_t crc32; 2294 2295 /* Program the MC hash registers. 2296 * The MAC hash registers are used to help discard unwanted 2297 * multicast packets as they are received from the external 2298 * media. The destination address is fed into the normal CRC 2299 * algorithm in order to generate a hash function. The most 2300 * significant bits of the CRC are then used without any inversion 2301 * in reverse order to index into a hash table which is comprised 2302 * of these MAC hash registers. If the CRC is calculated by 2303 * shifting right then the rightmost bits of the CRC can be 2304 * directly used with no additional inversion or bit swapping 2305 * required. All four MAC hash registers are used such that 2306 * register 1 bit-32 is the most significant hash table entry 2307 * and register 8 bit-0 is the least significant hash table entry. 2308 * This follows the normal big-endian ordering used throughout 2309 * Teton. Since there are 256 hash table entries, 8-bits are 2310 * used from the CRC. The hash registers are ignored if the 2311 * receive MAC is in promiscuous mode. */ 2312 for(idx = 0; idx < NUM_MC_HASH_REGISTERS; idx++) 2313 { 2314 hash_reg[idx] = 0; 2315 } 2316 2317 for(idx = 0; idx < mc_table->entry_cnt; idx++) 2318 { 2319 crc32 = compute_crc32( 2320 mc_table->addr_arr[idx].mc_addr, 2321 ETHERNET_ADDRESS_SIZE); 2322 2323 /* The most significant 7 bits of the CRC32 (no inversion), 2324 * are used to index into one of the possible 128 bit positions. */ 2325 bit_pos = ~crc32 & 0xff; 2326 2327 reg_idx = (bit_pos & 0xe0) >> 5; 2328 2329 bit_pos &= 0x1f; 2330 2331 hash_reg[reg_idx] |= (1 << bit_pos); 2332 } 2333 2334 for(idx = 0; idx < NUM_MC_HASH_REGISTERS; idx++) 2335 { 2336 REG_WR(pdev, emac.emac_multicast_hash[idx], hash_reg[idx]); 2337 } 2338 } /* set_mc_hash_reg */ 2339 2340 2341 2342 /******************************************************************************* 2343 * Description: 2344 * 2345 * Return: 2346 ******************************************************************************/ 2347 lm_status_t 2348 lm_set_rx_mask( 2349 lm_device_t *pdev, 2350 u32_t user_idx, 2351 lm_rx_mask_t rx_mask) 2352 { 2353 u32_t combined_rx_mask; 2354 u32_t invalid_rx_mask; 2355 u32_t sort_mode; 2356 u32_t rx_mode; 2357 u32_t val; 2358 u32_t idx; 2359 2360 if(user_idx >= MAX_RX_FILTER_USER_CNT) 2361 { 2362 DbgBreakMsg("invalid user index.\n"); 2363 2364 return LM_STATUS_FAILURE; 2365 } 2366 2367 combined_rx_mask = rx_mask; 2368 for(idx = 0; idx < MAX_RX_FILTER_USER_CNT; idx++) 2369 { 2370 if(idx != user_idx) 2371 { 2372 combined_rx_mask |= pdev->rx_info.mask[idx]; 2373 } 2374 } 2375 2376 /* Set up the rx_mode register. */ 2377 invalid_rx_mask = combined_rx_mask; 2378 REG_RD(pdev, emac.emac_rx_mode, &rx_mode); 2379 2380 if(invalid_rx_mask & LM_RX_MASK_ACCEPT_UNICAST) 2381 { 2382 invalid_rx_mask &= ~LM_RX_MASK_ACCEPT_UNICAST; 2383 } 2384 2385 if(invalid_rx_mask & LM_RX_MASK_ACCEPT_MULTICAST) 2386 { 2387 invalid_rx_mask &= ~LM_RX_MASK_ACCEPT_MULTICAST; 2388 } 2389 2390 if(invalid_rx_mask & LM_RX_MASK_ACCEPT_ALL_MULTICAST) 2391 { 2392 invalid_rx_mask &= ~LM_RX_MASK_ACCEPT_ALL_MULTICAST; 2393 } 2394 2395 rx_mode &= ~EMAC_RX_MODE_FILT_BROADCAST; 2396 if(invalid_rx_mask & LM_RX_MASK_ACCEPT_BROADCAST) 2397 { 2398 invalid_rx_mask &= ~LM_RX_MASK_ACCEPT_BROADCAST; 2399 } 2400 else 2401 { 2402 rx_mode |= EMAC_RX_MODE_FILT_BROADCAST; 2403 } 2404 2405 rx_mode &= ~(EMAC_RX_MODE_ACCEPT_RUNTS | EMAC_RX_MODE_ACCEPT_OVERSIZE); 2406 if(invalid_rx_mask & LM_RX_MASK_ACCEPT_ERROR_PACKET) 2407 { 2408 invalid_rx_mask &= ~LM_RX_MASK_ACCEPT_ERROR_PACKET; 2409 rx_mode |= EMAC_RX_MODE_ACCEPT_RUNTS | 2410 EMAC_RX_MODE_ACCEPT_OVERSIZE | 2411 EMAC_RX_MODE_NO_CRC_CHK; 2412 } 2413 2414 rx_mode &= ~EMAC_RX_MODE_PROMISCUOUS; 2415 if(invalid_rx_mask & LM_RX_MASK_PROMISCUOUS_MODE) 2416 { 2417 invalid_rx_mask &= ~LM_RX_MASK_PROMISCUOUS_MODE; 2418 rx_mode |= EMAC_RX_MODE_PROMISCUOUS; 2419 } 2420 2421 if(invalid_rx_mask) 2422 { 2423 DbgBreakMsg("Unknown rx_mask.\n"); 2424 2425 return LM_STATUS_FAILURE; 2426 } 2427 2428 if(combined_rx_mask & LM_RX_MASK_ACCEPT_ALL_MULTICAST) 2429 { 2430 for(idx = 0; idx < NUM_MC_HASH_REGISTERS; idx++) 2431 { 2432 REG_WR(pdev, emac.emac_multicast_hash[idx], 0xffffffff); 2433 } 2434 } 2435 else if(combined_rx_mask & LM_RX_MASK_ACCEPT_MULTICAST) 2436 { 2437 set_mc_hash_reg(pdev, &pdev->mc_table); 2438 } 2439 else 2440 { 2441 for(idx = 0; idx < NUM_MC_HASH_REGISTERS; idx++) 2442 { 2443 REG_WR(pdev, emac.emac_multicast_hash[idx], 0); 2444 } 2445 } 2446 2447 pdev->rx_info.mask[user_idx] = rx_mask; 2448 2449 val = rx_mode | EMAC_RX_MODE_SORT_MODE; 2450 if(pdev->params.keep_vlan_tag) 2451 { 2452 val |= EMAC_RX_MODE_KEEP_VLAN_TAG; 2453 } 2454 REG_WR(pdev, emac.emac_rx_mode, val); 2455 2456 /* Set up the sort_mode register. */ 2457 sort_mode = 0; 2458 2459 if(rx_mask & LM_RX_MASK_ACCEPT_UNICAST) 2460 { 2461 sort_mode |= 1 << user_idx; 2462 } 2463 2464 if(rx_mask & LM_RX_MASK_ACCEPT_MULTICAST) 2465 { 2466 sort_mode |= RPM_SORT_USER0_MC_HSH_EN; 2467 } 2468 2469 if(rx_mask & LM_RX_MASK_ACCEPT_ALL_MULTICAST) 2470 { 2471 sort_mode |= RPM_SORT_USER0_MC_EN; 2472 } 2473 2474 if(rx_mask & LM_RX_MASK_ACCEPT_BROADCAST) 2475 { 2476 sort_mode |= RPM_SORT_USER0_BC_EN; 2477 } 2478 2479 if(rx_mask & LM_RX_MASK_PROMISCUOUS_MODE) 2480 { 2481 sort_mode |= RPM_SORT_USER0_PROM_EN | RPM_SORT_USER0_PROM_VLAN; 2482 } 2483 2484 switch(user_idx) 2485 { 2486 case RX_FILTER_USER_IDX0: 2487 REG_RD(pdev, rpm.rpm_sort_user0, &val); 2488 2489 REG_WR(pdev, rpm.rpm_sort_user0, 0x00000000); 2490 REG_WR(pdev, rpm.rpm_sort_user0, sort_mode); 2491 2492 val &= 0xffff; 2493 val &= ~(1 << user_idx); 2494 2495 sort_mode |= val | RPM_SORT_USER0_ENA; 2496 REG_WR(pdev, rpm.rpm_sort_user0, sort_mode); 2497 break; 2498 2499 case RX_FILTER_USER_IDX1: 2500 REG_RD(pdev, rpm.rpm_sort_user1, &val); 2501 2502 REG_WR(pdev, rpm.rpm_sort_user1, 0x00000000); 2503 REG_WR(pdev, rpm.rpm_sort_user1, sort_mode); 2504 2505 val &= 0xffff; 2506 val &= ~(1 << user_idx); 2507 2508 sort_mode |= val | RPM_SORT_USER0_ENA; 2509 REG_WR(pdev, rpm.rpm_sort_user1, sort_mode); 2510 break; 2511 2512 case RX_FILTER_USER_IDX2: 2513 REG_RD(pdev, rpm.rpm_sort_user2, &val); 2514 2515 REG_WR(pdev, rpm.rpm_sort_user2, 0x00000000); 2516 REG_WR(pdev, rpm.rpm_sort_user2, sort_mode); 2517 2518 val &= 0xffff; 2519 val &= ~(1 << user_idx); 2520 2521 sort_mode |= val | RPM_SORT_USER0_ENA; 2522 REG_WR(pdev, rpm.rpm_sort_user2, sort_mode); 2523 break; 2524 2525 case RX_FILTER_USER_IDX3: 2526 REG_RD(pdev, rpm.rpm_sort_user3, &val); 2527 2528 REG_WR(pdev, rpm.rpm_sort_user3, 0x00000000); 2529 REG_WR(pdev, rpm.rpm_sort_user3, sort_mode); 2530 2531 val &= 0xffff; 2532 val &= ~(1 << user_idx); 2533 2534 sort_mode |= val | RPM_SORT_USER0_ENA; 2535 REG_WR(pdev, rpm.rpm_sort_user3, sort_mode); 2536 break; 2537 2538 default: 2539 DbgBreakMsg("invalid user idx.\n"); 2540 2541 break; 2542 } 2543 2544 /* Set rx_flood for L2. */ 2545 REG_RD_IND(pdev, 0xe0024, &val); 2546 val &= ~(1 << user_idx); 2547 2548 if(rx_mask & (LM_RX_MASK_ACCEPT_MULTICAST | 2549 LM_RX_MASK_ACCEPT_ALL_MULTICAST | 2550 LM_RX_MASK_ACCEPT_BROADCAST | 2551 LM_RX_MASK_PROMISCUOUS_MODE)) 2552 { 2553 val |= (1 << user_idx); 2554 } 2555 2556 REG_WR_IND(pdev, 0xe0024, val); 2557 2558 return LM_STATUS_SUCCESS; 2559 } /* lm_set_rx_mask */ 2560 2561 2562 2563 /******************************************************************************* 2564 * Description: 2565 * 2566 * Return: 2567 ******************************************************************************/ 2568 lm_status_t 2569 lm_add_mc( 2570 lm_device_t *pdev, 2571 u8_t *mc_addr) 2572 { 2573 lm_mc_entry_t *mc_entry; 2574 u32_t cnt; 2575 2576 DbgMessage(pdev, VERBOSE, "### lm_add_mc\n"); 2577 2578 for(cnt = 0; cnt < pdev->mc_table.entry_cnt; cnt++) 2579 { 2580 mc_entry = &pdev->mc_table.addr_arr[cnt]; 2581 2582 if(IS_ETH_ADDRESS_EQUAL(mc_entry->mc_addr, mc_addr)) 2583 { 2584 mc_entry->ref_cnt++; 2585 2586 return LM_STATUS_SUCCESS; 2587 } 2588 } 2589 2590 if(pdev->mc_table.entry_cnt >= LM_MAX_MC_TABLE_SIZE) 2591 { 2592 DbgBreakMsg("No entry in MC table\n"); 2593 2594 return LM_STATUS_FAILURE; 2595 } 2596 2597 mc_entry = &pdev->mc_table.addr_arr[pdev->mc_table.entry_cnt]; 2598 pdev->mc_table.entry_cnt++; 2599 2600 mc_entry->ref_cnt = 1; 2601 2602 COPY_ETH_ADDRESS(mc_addr, mc_entry->mc_addr); 2603 2604 (void) lm_set_rx_mask( 2605 pdev, 2606 RX_FILTER_USER_IDX0, 2607 pdev->rx_info.mask[RX_FILTER_USER_IDX0] | LM_RX_MASK_ACCEPT_MULTICAST); 2608 2609 return LM_STATUS_SUCCESS; 2610 } /* lm_add_mc */ 2611 2612 2613 2614 /******************************************************************************* 2615 * Description: 2616 * 2617 * Return: 2618 ******************************************************************************/ 2619 lm_status_t 2620 lm_del_mc( 2621 lm_device_t *pdev, 2622 u8_t *mc_addr) 2623 { 2624 lm_mc_entry_t *mc_entry; 2625 u32_t cnt; 2626 2627 for(cnt = 0; cnt < pdev->mc_table.entry_cnt; cnt++) 2628 { 2629 mc_entry = &pdev->mc_table.addr_arr[cnt]; 2630 2631 if(IS_ETH_ADDRESS_EQUAL(mc_entry->mc_addr, mc_addr)) 2632 { 2633 mc_entry->ref_cnt--; 2634 2635 /* No more instance left, remove the address from the table. 2636 * Move the last entry in the table to the deleted slot. */ 2637 if(mc_entry->ref_cnt == 0) 2638 { 2639 if(pdev->mc_table.entry_cnt > 1) 2640 { 2641 *mc_entry = pdev->mc_table.addr_arr[pdev->mc_table.entry_cnt-1]; 2642 } 2643 2644 pdev->mc_table.entry_cnt--; 2645 2646 /* Update the receive mask if the table is empty. */ 2647 if(pdev->mc_table.entry_cnt == 0) 2648 { 2649 pdev->rx_info.mask[RX_FILTER_USER_IDX0] &= 2650 ~LM_RX_MASK_ACCEPT_MULTICAST; 2651 } 2652 2653 (void) lm_set_rx_mask( 2654 pdev, 2655 RX_FILTER_USER_IDX0, 2656 pdev->rx_info.mask[RX_FILTER_USER_IDX0]); 2657 } 2658 2659 return LM_STATUS_SUCCESS; 2660 } 2661 } 2662 2663 DbgBreakMsg("Mc address not in the table\n"); 2664 2665 return LM_STATUS_FAILURE; 2666 } /* lm_del_mc */ 2667 2668 2669 2670 /******************************************************************************* 2671 * Description: 2672 * 2673 * Return: 2674 ******************************************************************************/ 2675 void 2676 lm_clear_mc(lm_device_t *pdev) 2677 { 2678 DbgMessage(pdev, VERBOSE, "### lm_clear_mc\n"); 2679 2680 pdev->mc_table.entry_cnt = 0; 2681 2682 (void) lm_set_rx_mask( 2683 pdev, 2684 RX_FILTER_USER_IDX0, 2685 pdev->rx_info.mask[RX_FILTER_USER_IDX0] & ~LM_RX_MASK_ACCEPT_MULTICAST); 2686 } /* lm_clear_mc */ 2687 2688 2689 2690 /******************************************************************************* 2691 * Description: 2692 * 2693 * Return: 2694 ******************************************************************************/ 2695 lm_status_t 2696 lm_get_stats( 2697 lm_device_t *pdev, 2698 lm_stats_t stats_type, 2699 u64_t *stats_cnt) 2700 { 2701 volatile statistics_block_t *sb; 2702 lm_status_t lm_status; 2703 lm_u64_t *stats; 2704 u32_t reg_val; 2705 u32_t val; 2706 2707 // 2708 // The fix of CQ#29454 caused CQ#30307 - 2709 // Bacs: Bogus counters on 5708 under statistics tab 2710 // So far, Windows never see CQ#29454 problem. 2711 // Remove the fix right now 2712 // 2713 2714 /* CQ#29454 - statistics corruption. */ 2715 //REG_RD(pdev, hc.hc_stats_ticks, &val); 2716 //REG_WR(pdev, hc.hc_stats_ticks, 0); 2717 2718 REG_WR(pdev, hc.hc_command, HC_COMMAND_STATS_NOW); 2719 REG_RD(pdev, hc.hc_command, ®_val); 2720 mm_wait(pdev, 5); 2721 2722 lm_status = LM_STATUS_SUCCESS; 2723 sb = pdev->vars.stats_virt; 2724 stats = (lm_u64_t *) stats_cnt; 2725 2726 switch(stats_type) 2727 { 2728 case LM_STATS_FRAMES_XMITTED_OK: 2729 stats->as_u32.low = sb->stat_IfHCOutUcastPkts_lo; 2730 stats->as_u32.high = sb->stat_IfHCOutUcastPkts_hi; 2731 2732 LM_INC64(stats, sb->stat_IfHCOutMulticastPkts_lo); 2733 stats->as_u32.high += sb->stat_IfHCOutMulticastPkts_hi; 2734 2735 LM_INC64(stats, sb->stat_IfHCOutBroadcastPkts_lo); 2736 stats->as_u32.high += sb->stat_IfHCOutBroadcastPkts_hi; 2737 break; 2738 2739 case LM_STATS_FRAMES_RECEIVED_OK: 2740 stats->as_u32.low = sb->stat_IfHCInUcastPkts_lo; 2741 stats->as_u32.high = sb->stat_IfHCInUcastPkts_hi; 2742 2743 LM_INC64(stats, sb->stat_IfHCInMulticastPkts_lo); 2744 stats->as_u32.high += sb->stat_IfHCInMulticastPkts_hi; 2745 2746 LM_INC64(stats, sb->stat_IfHCInBroadcastPkts_lo); 2747 stats->as_u32.high += sb->stat_IfHCInBroadcastPkts_hi; 2748 REG_RD_IND( 2749 pdev, 2750 OFFSETOF(reg_space_t, 2751 com.com_scratch[0])+ 2752 COM_HSI_OFFSETOFF(com_l2_iscsi_no_buffer), 2753 &val); 2754 if((stats->as_u32.high == 0 && stats->as_u32.low) && 2755 (stats->as_u32.low < val)) 2756 { 2757 /* due to asynchrous nature of reading the counters 2758 * from status block and reading the counters from 2759 * chip scratchpad mem, it is possible that the values 2760 * are out of syn */ 2761 stats->as_u32.low = 0; 2762 } 2763 else 2764 { 2765 LM_DEC64(stats, val); 2766 } 2767 2768 REG_RD_IND( 2769 pdev, 2770 OFFSETOF(reg_space_t, 2771 com.com_scratch[0])+ 2772 COM_HSI_OFFSETOFF(com_l2_no_buffer), 2773 &val); 2774 if((stats->as_u32.high == 0 && stats->as_u32.low) && 2775 (stats->as_u32.low < val)) 2776 { 2777 /* due to asynchrous nature of reading the counters 2778 * from status block and reading the counters from 2779 * chip scratchpad mem, it is possible that the values 2780 * are out of syn */ 2781 stats->as_u32.low = 0; 2782 } 2783 else 2784 { 2785 LM_DEC64(stats, val); 2786 } 2787 break; 2788 2789 case LM_STATS_ERRORED_RECEIVE_CNT: 2790 stats->as_u32.low = pdev->rx_info.stats.err; 2791 stats->as_u32.high = 0; 2792 break; 2793 2794 case LM_STATS_RCV_CRC_ERROR: 2795 stats->as_u32.low = sb->stat_Dot3StatsFCSErrors; 2796 stats->as_u32.high = 0; 2797 break; 2798 2799 case LM_STATS_ALIGNMENT_ERROR: 2800 stats->as_u32.low = sb->stat_Dot3StatsAlignmentErrors; 2801 stats->as_u32.high = 0; 2802 break; 2803 2804 case LM_STATS_SINGLE_COLLISION_FRAMES: 2805 stats->as_u32.low = sb->stat_Dot3StatsSingleCollisionFrames; 2806 stats->as_u32.high = 0; 2807 break; 2808 2809 case LM_STATS_MULTIPLE_COLLISION_FRAMES: 2810 stats->as_u32.low = sb->stat_Dot3StatsMultipleCollisionFrames; 2811 stats->as_u32.high = 0; 2812 break; 2813 2814 case LM_STATS_FRAMES_DEFERRED: 2815 stats->as_u32.low = sb->stat_Dot3StatsDeferredTransmissions; 2816 stats->as_u32.high = 0; 2817 break; 2818 2819 case LM_STATS_MAX_COLLISIONS: 2820 stats->as_u32.low = sb->stat_Dot3StatsExcessiveCollisions; 2821 break; 2822 2823 case LM_STATS_UNICAST_FRAMES_XMIT: 2824 stats->as_u32.low = sb->stat_IfHCOutUcastPkts_lo; 2825 stats->as_u32.high = sb->stat_IfHCOutUcastPkts_hi; 2826 break; 2827 2828 case LM_STATS_MULTICAST_FRAMES_XMIT: 2829 stats->as_u32.low = sb->stat_IfHCOutMulticastPkts_lo; 2830 stats->as_u32.high = sb->stat_IfHCOutMulticastPkts_hi; 2831 break; 2832 2833 case LM_STATS_BROADCAST_FRAMES_XMIT: 2834 stats->as_u32.low = sb->stat_IfHCOutBroadcastPkts_lo; 2835 stats->as_u32.high = sb->stat_IfHCOutBroadcastPkts_hi; 2836 break; 2837 2838 case LM_STATS_UNICAST_FRAMES_RCV: 2839 stats->as_u32.low = sb->stat_IfHCInUcastPkts_lo; 2840 stats->as_u32.high = sb->stat_IfHCInUcastPkts_hi; 2841 REG_RD_IND( 2842 pdev, 2843 OFFSETOF(reg_space_t, 2844 com.com_scratch[0])+ 2845 COM_HSI_OFFSETOFF(com_unicast_no_buffer), 2846 &val); 2847 if((stats->as_u32.high == 0 && stats->as_u32.low) && 2848 (stats->as_u32.low < val)) 2849 { 2850 /* due to asynchrous nature of reading the counters 2851 * from status block and reading the counters from 2852 * chip scratchpad mem, it is possible that the values 2853 * are out of syn */ 2854 stats->as_u32.low = 0; 2855 } 2856 else 2857 { 2858 LM_DEC64(stats, val); 2859 } 2860 break; 2861 2862 case LM_STATS_MULTICAST_FRAMES_RCV: 2863 stats->as_u32.low = sb->stat_IfHCInMulticastPkts_lo; 2864 stats->as_u32.high = sb->stat_IfHCInMulticastPkts_hi; 2865 REG_RD_IND( 2866 pdev, 2867 OFFSETOF(reg_space_t, 2868 com.com_scratch[0])+ 2869 COM_HSI_OFFSETOFF(com_mcast_no_buffer), 2870 &val); 2871 2872 if((stats->as_u32.high == 0 && stats->as_u32.low) && 2873 (stats->as_u32.low < val)) 2874 { 2875 /* due to asynchrous nature of reading the counters 2876 * from status block and reading the counters from 2877 * chip scratchpad mem, it is possible that the values 2878 * are out of syn */ 2879 stats->as_u32.low = 0; 2880 } 2881 else 2882 { 2883 LM_DEC64(stats, val); 2884 } 2885 break; 2886 2887 case LM_STATS_BROADCAST_FRAMES_RCV: 2888 stats->as_u32.low = sb->stat_IfHCInBroadcastPkts_lo; 2889 stats->as_u32.high = sb->stat_IfHCInBroadcastPkts_hi; 2890 REG_RD_IND( 2891 pdev, 2892 OFFSETOF(reg_space_t, 2893 com.com_scratch[0])+ 2894 COM_HSI_OFFSETOFF(com_bcast_no_buffer), 2895 &val); 2896 if((stats->as_u32.high == 0 && stats->as_u32.low) && 2897 (stats->as_u32.low < val)) 2898 { 2899 /* due to asynchrous nature of reading the counters 2900 * from status block and reading the counters from 2901 * chip scratchpad mem, it is possible that the values 2902 * are out of syn */ 2903 stats->as_u32.low = 0; 2904 } 2905 else 2906 { 2907 LM_DEC64(stats, val); 2908 } 2909 break; 2910 2911 case LM_STATS_ERRORED_TRANSMIT_CNT: 2912 case LM_STATS_RCV_OVERRUN: 2913 case LM_STATS_XMIT_UNDERRUN: 2914 /* These counters are always zero. */ 2915 stats->as_u32.low = 0; 2916 stats->as_u32.high = 0; 2917 break; 2918 2919 case LM_STATS_RCV_NO_BUFFER_DROP: 2920 /* com_no_buffer */ 2921 REG_RD_IND( 2922 pdev, 2923 OFFSETOF(reg_space_t, com.com_scratch[0])+COM_HSI_OFFSETOFF(com_unicast_no_buffer), 2924 &val); 2925 stats->as_u32.low = val; 2926 REG_RD_IND( 2927 pdev, 2928 OFFSETOF(reg_space_t, com.com_scratch[0])+COM_HSI_OFFSETOFF(com_mcast_no_buffer), 2929 &val); 2930 stats->as_u32.low += val; 2931 REG_RD_IND( 2932 pdev, 2933 OFFSETOF(reg_space_t, com.com_scratch[0])+COM_HSI_OFFSETOFF(com_bcast_no_buffer), 2934 &val); 2935 stats->as_u32.low += val; 2936 2937 stats->as_u32.high = 0; 2938 break; 2939 2940 case LM_STATS_BYTES_RCV: 2941 stats->as_u32.low = sb->stat_IfHCInOctets_lo; 2942 stats->as_u32.high = sb->stat_IfHCInOctets_hi; 2943 break; 2944 2945 case LM_STATS_BYTES_XMIT: 2946 stats->as_u32.low = sb->stat_IfHCOutOctets_lo; 2947 stats->as_u32.high = sb->stat_IfHCOutOctets_hi; 2948 break; 2949 2950 case LM_STATS_IF_IN_DISCARDS: 2951 /* com_no_buffer */ 2952 REG_RD_IND( 2953 pdev, 2954 OFFSETOF(reg_space_t, com.com_scratch[0])+COM_HSI_OFFSETOFF(com_unicast_no_buffer), 2955 &val); 2956 stats->as_u32.low = val; 2957 REG_RD_IND( 2958 pdev, 2959 OFFSETOF(reg_space_t, com.com_scratch[0])+COM_HSI_OFFSETOFF(com_mcast_no_buffer), 2960 &val); 2961 stats->as_u32.low += val; 2962 REG_RD_IND( 2963 pdev, 2964 OFFSETOF(reg_space_t, com.com_scratch[0])+COM_HSI_OFFSETOFF(com_bcast_no_buffer), 2965 &val); 2966 stats->as_u32.low += val; 2967 stats->as_u32.low += sb->stat_Dot3StatsFCSErrors; 2968 2969 stats->as_u32.high = 0; 2970 break; 2971 2972 case LM_STATS_XMIT_DISCARDS: 2973 case LM_STATS_IF_IN_ERRORS: 2974 case LM_STATS_IF_OUT_ERRORS: 2975 stats->as_u32.low = 0; 2976 stats->as_u32.high = 0; 2977 break; 2978 2979 case LM_STATS_DIRECTED_BYTES_RCV: 2980 /* rxp_unicast_bytes_rcvd */ 2981 REG_RD_IND( 2982 pdev, 2983 OFFSETOF(reg_space_t, rxp.rxp_scratch[0])+RXP_HSI_OFFSETOFF(rxp_unicast_bytes_rcvd)+4, 2984 &stats->as_u32.low); 2985 REG_RD_IND( 2986 pdev, 2987 OFFSETOF(reg_space_t, rxp.rxp_scratch[0])+RXP_HSI_OFFSETOFF(rxp_unicast_bytes_rcvd), 2988 &stats->as_u32.high); 2989 break; 2990 2991 case LM_STATS_MULTICAST_BYTES_RCV: 2992 /* rxp_multicast_bytes_rcvd */ 2993 REG_RD_IND( 2994 pdev, 2995 OFFSETOF(reg_space_t, rxp.rxp_scratch[0])+RXP_HSI_OFFSETOFF(rxp_multicast_bytes_rcvd)+4, 2996 &stats->as_u32.low); 2997 REG_RD_IND( 2998 pdev, 2999 OFFSETOF(reg_space_t, rxp.rxp_scratch[0])+RXP_HSI_OFFSETOFF(rxp_multicast_bytes_rcvd), 3000 &stats->as_u32.high); 3001 break; 3002 3003 case LM_STATS_BROADCAST_BYTES_RCV: 3004 /* rxp_broadcast_bytes_rcvd */ 3005 REG_RD_IND( 3006 pdev, 3007 OFFSETOF(reg_space_t, rxp.rxp_scratch[0])+RXP_HSI_OFFSETOFF(rxp_broadcast_bytes_rcvd)+4, 3008 &stats->as_u32.low); 3009 REG_RD_IND( 3010 pdev, 3011 OFFSETOF(reg_space_t, rxp.rxp_scratch[0])+RXP_HSI_OFFSETOFF(rxp_broadcast_bytes_rcvd), 3012 &stats->as_u32.high); 3013 break; 3014 3015 case LM_STATS_DIRECTED_BYTES_XMIT: 3016 /* unicast_bytes_xmit_lo */ 3017 REG_RD_IND( 3018 pdev, 3019 OFFSETOF(reg_space_t, tpat.tpat_scratch[0])+TPAT_HSI_OFFSETOFF(unicast_bytes_xmit)+4, 3020 &stats->as_u32.low); 3021 REG_RD_IND( 3022 pdev, 3023 OFFSETOF(reg_space_t, tpat.tpat_scratch[0])+TPAT_HSI_OFFSETOFF(unicast_bytes_xmit), 3024 &stats->as_u32.high); 3025 break; 3026 3027 case LM_STATS_MULTICAST_BYTES_XMIT: 3028 /* multicast_bytes_xmit */ 3029 REG_RD_IND( 3030 pdev, 3031 OFFSETOF(reg_space_t, tpat.tpat_scratch[0])+TPAT_HSI_OFFSETOFF(multicast_bytes_xmit)+4, 3032 &stats->as_u32.low); 3033 REG_RD_IND( 3034 pdev, 3035 OFFSETOF(reg_space_t, tpat.tpat_scratch[0])+TPAT_HSI_OFFSETOFF(multicast_bytes_xmit), 3036 &stats->as_u32.high); 3037 break; 3038 3039 case LM_STATS_BROADCAST_BYTES_XMIT: 3040 /* broadcast_bytes_xmit */ 3041 REG_RD_IND( 3042 pdev, 3043 OFFSETOF(reg_space_t, tpat.tpat_scratch[0])+TPAT_HSI_OFFSETOFF(broadcast_bytes_xmit)+4, 3044 &stats->as_u32.low); 3045 REG_RD_IND( 3046 pdev, 3047 OFFSETOF(reg_space_t, tpat.tpat_scratch[0])+TPAT_HSI_OFFSETOFF(broadcast_bytes_xmit), 3048 &stats->as_u32.high); 3049 break; 3050 3051 default: 3052 stats->as_u32.low = 0; 3053 stats->as_u32.high = 0; 3054 3055 lm_status = LM_STATUS_INVALID_PARAMETER; 3056 break; 3057 } 3058 3059 //REG_WR(pdev, hc.hc_stats_ticks, val); 3060 3061 return lm_status; 3062 } /* lm_get_stats */ 3063 3064 3065 3066 /******************************************************************************* 3067 * Description: 3068 * 3069 * Return: 3070 ******************************************************************************/ 3071 STATIC lm_nwuf_t * 3072 find_nwuf( 3073 lm_nwuf_list_t *nwuf_list, 3074 u32_t mask_size, 3075 u8_t *byte_mask, 3076 u8_t *pattern, 3077 u32_t max_nwuf_cnt) 3078 { 3079 lm_nwuf_t *nwuf; 3080 u8_t found; 3081 u32_t idx; 3082 u32_t j; 3083 u32_t k; 3084 3085 for(idx = 0; idx < max_nwuf_cnt; idx++) 3086 { 3087 nwuf = &nwuf_list->nwuf_arr[idx]; 3088 3089 if((nwuf->size&0xffff) != mask_size) 3090 { 3091 continue; 3092 } 3093 3094 found = TRUE; 3095 for(j = 0; j < mask_size && found == TRUE; j++) 3096 { 3097 if(nwuf->mask[j] != byte_mask[j]) 3098 { 3099 found = FALSE; 3100 break; 3101 } 3102 3103 for(k = 0; k < 8; k++) 3104 { 3105 if((byte_mask[j] & (1 << k)) && 3106 (nwuf->pattern[j*8 + k] != pattern[j*8 + k])) 3107 { 3108 found = FALSE; 3109 break; 3110 } 3111 } 3112 } 3113 3114 if(found) 3115 { 3116 return nwuf; 3117 } 3118 } 3119 3120 return NULL; 3121 } /* find_nwuf */ 3122 3123 3124 3125 /******************************************************************************* 3126 * Description: 3127 * 3128 * Return: 3129 ******************************************************************************/ 3130 lm_status_t 3131 lm_add_nwuf( 3132 lm_device_t *pdev, 3133 u32_t pattern_size, 3134 u32_t mask_size, 3135 u8_t *byte_mask, 3136 u8_t *pattern) 3137 { 3138 lm_nwuf_t *nwuf; 3139 u32_t idx; 3140 /* 3141 u32_t i; 3142 */ 3143 u32_t j; 3144 u32_t k; 3145 u32_t l; 3146 u32_t combind_size; 3147 u32_t max_nwuf_cnt; 3148 3149 if(CHIP_NUM(pdev) == CHIP_NUM_5709) 3150 { 3151 max_nwuf_cnt = LM_MAX_NWUF_CNT_5709; 3152 } 3153 else 3154 { 3155 max_nwuf_cnt = LM_MAX_NWUF_CNT; 3156 } 3157 3158 combind_size = (pattern_size<<16) & 0xffff0000; 3159 combind_size |= mask_size; 3160 pattern_size &= 0xffff; 3161 mask_size &= 0xffff; 3162 3163 3164 //DbgBreakIf(mask_size == 0xc &&pattern_size == 0x4a); 3165 3166 3167 if(mask_size == 0 || mask_size > LM_NWUF_PATTERN_MASK_SIZE) 3168 { 3169 DbgBreakMsg("Invalid byte mask size\n"); 3170 3171 return LM_STATUS_FAILURE; 3172 } 3173 3174 /* If this is a duplicate entry, we are done. */ 3175 nwuf = find_nwuf( 3176 &pdev->nwuf_list, 3177 mask_size, 3178 byte_mask, pattern, 3179 max_nwuf_cnt); 3180 3181 if(nwuf) 3182 { 3183 DbgMessage(pdev, INFORM, "Duplicated nwuf entry.\n"); 3184 3185 return LM_STATUS_EXISTING_OBJECT; 3186 } 3187 3188 /* Find an empty slot. */ 3189 nwuf = NULL; 3190 for(idx = 0; idx < max_nwuf_cnt; idx++) 3191 { 3192 if(pdev->nwuf_list.nwuf_arr[idx].size == 0) 3193 { 3194 nwuf = &pdev->nwuf_list.nwuf_arr[idx]; 3195 break; 3196 } 3197 } 3198 3199 /* 3200 * LHDBG_PRINT(("%p Adding NWUF[%d], mask size: %d, pattern size: %d\n", 3201 pdev,idx,mask_size,pattern_size)); 3202 LHDBG_PRINT(("mask array:\n")); 3203 3204 for (i=0;i<mask_size;i++) 3205 { 3206 if (0 == i%16) LH_PRINTK(("\n")); 3207 LH_PRINTK(("%02x ", byte_mask[i])); 3208 } 3209 LH_PRINTK(("\npattern:\n")); 3210 3211 for (i=0;i<mask_size;i++) 3212 { 3213 for (j=0;j<8;j++) 3214 { 3215 if (0 == (i*8+j)%16) 3216 { 3217 LH_PRINTK(("\n")); 3218 } 3219 if (byte_mask[i] & 1<<j) 3220 { 3221 LH_PRINTK(("[%02x] ",pattern[i*8+j])); 3222 } 3223 else 3224 { 3225 if (pattern_size && i*8+j>=pattern_size) 3226 { 3227 LH_PRINTK(("-%02x- ",pattern[i*8+j])); 3228 } 3229 else 3230 { 3231 LH_PRINTK((" %02x ",pattern[i*8+j])); 3232 } 3233 3234 } 3235 } 3236 } 3237 LH_PRINTK(("\n")); 3238 */ 3239 3240 if(nwuf == NULL) 3241 { 3242 DbgMessage(pdev, WARN, "Cannot add Nwuf, exceeded maximum.\n"); 3243 3244 return LM_STATUS_RESOURCE; 3245 } 3246 3247 pdev->nwuf_list.cnt++; 3248 3249 /* Save nwuf data. */ 3250 nwuf->size = mask_size; 3251 3252 if (pattern_size) 3253 { 3254 nwuf->size = combind_size; 3255 goto _handle_win7_pattern; 3256 } 3257 3258 for(j = 0; j < mask_size; j++) 3259 { 3260 nwuf->mask[j] = byte_mask[j]; 3261 3262 for(k = 0; k < 8; k++) 3263 { 3264 if(byte_mask[j] & (1 << k)) 3265 { 3266 nwuf->pattern[j*8 + k] = pattern[j*8 + k]; 3267 } 3268 else 3269 { 3270 nwuf->pattern[j*8 + k] = 0; 3271 } 3272 } 3273 } 3274 3275 /* The byte patterns immediately following the byte that is enabled 3276 * for comparision need to be set to 0xff. This will help facilitate 3277 * the programming of pattern onto the chip. The end of the pattern is 3278 * indicated by the first 0xff byte that is not enabled for comparision. */ 3279 if(byte_mask[mask_size-1]) 3280 { 3281 k = 8; 3282 while(k) 3283 { 3284 k--; 3285 if(byte_mask[mask_size-1] & (1 << k)) 3286 { 3287 break; 3288 } 3289 3290 nwuf->pattern[(mask_size-1)*8 + k] = 0xff; 3291 } 3292 } 3293 3294 /* Set the rest of the pattern to 0xff. */ 3295 for(j = mask_size; j < LM_NWUF_PATTERN_MASK_SIZE; j++) 3296 { 3297 nwuf->mask[j] = 0; 3298 3299 for(k = 0; k < 8; k++) 3300 { 3301 nwuf->pattern[j*8 + k] = 0xff; 3302 } 3303 } 3304 /* 3305 LHDBG_PRINT(("Dumping pattern before return\n")); 3306 for (i=0;i<128;i++) 3307 { 3308 if (i!=0 && i%16==0) 3309 { 3310 LH_PRINTK(("\n")); 3311 } 3312 3313 LH_PRINTK(("%02x ",nwuf->pattern[i])); 3314 3315 } 3316 LH_PRINTK(("\nEnd of add_nwuf\n")); 3317 */ 3318 return LM_STATUS_SUCCESS; 3319 _handle_win7_pattern: 3320 /* 3321 * this is new for win7 3322 */ 3323 l=0; 3324 3325 /*for lxdiag build*/ 3326 #ifdef LINUX 3327 { 3328 u8_t idx; 3329 for (idx=0; idx< LM_NWUF_PATTERN_MASK_SIZE; idx++) 3330 nwuf->mask[idx] = 0; 3331 } 3332 #else 3333 memset(nwuf->mask,0,LM_NWUF_PATTERN_MASK_SIZE); 3334 #endif 3335 3336 for(j = 0; j < mask_size ; j++) 3337 { 3338 nwuf->mask[j] = byte_mask[j]; 3339 3340 for(k = 0; k < 8 ; k++) 3341 { 3342 if ( l<pattern_size ) 3343 { 3344 if(byte_mask[j] & (1 << k)) 3345 { 3346 nwuf->pattern[j*8 + k] = pattern[j*8 + k]; 3347 } 3348 else 3349 { 3350 nwuf->pattern[j*8 + k] = 0; 3351 } 3352 } 3353 else 3354 { 3355 nwuf->pattern[j*8 + k] = 0xff; 3356 } 3357 l++; 3358 } 3359 } 3360 /* 3361 LHDBG_PRINT(("Dumping pattern before return\n")); 3362 for (i=0;i<128;i++) 3363 { 3364 if (i!=0 && i%16==0) 3365 { 3366 LH_PRINTK(("\n")); 3367 } 3368 3369 LH_PRINTK(("%02x ",nwuf->pattern[i])); 3370 3371 } 3372 LH_PRINTK(("\nEnd of add_nwuf\n")); 3373 */ 3374 return LM_STATUS_SUCCESS; 3375 } /* lm_add_nwuf */ 3376 3377 3378 /******************************************************************************* 3379 * Description: 3380 * 3381 * Return: 3382 ******************************************************************************/ 3383 lm_status_t 3384 lm_del_nwuf( 3385 lm_device_t *pdev, 3386 u32_t mask_size, 3387 u8_t *byte_mask, 3388 u8_t *pattern) 3389 { 3390 lm_nwuf_t *nwuf; 3391 u32_t k; 3392 u32_t max_nwuf_cnt; 3393 3394 if(CHIP_NUM(pdev) == CHIP_NUM_5709) 3395 { 3396 max_nwuf_cnt = LM_MAX_NWUF_CNT_5709; 3397 } 3398 else 3399 { 3400 max_nwuf_cnt = LM_MAX_NWUF_CNT; 3401 } 3402 3403 mask_size &= 0xffff; 3404 if(mask_size == 0 || mask_size > LM_NWUF_PATTERN_MASK_SIZE) 3405 { 3406 DbgBreakMsg("Invalid byte mask size\n"); 3407 3408 return LM_STATUS_FAILURE; 3409 } 3410 3411 /* Look for a matching pattern. */ 3412 nwuf = find_nwuf( 3413 &pdev->nwuf_list, 3414 mask_size, 3415 byte_mask, 3416 pattern, 3417 max_nwuf_cnt); 3418 3419 if(nwuf == NULL) 3420 { 3421 return LM_STATUS_OBJECT_NOT_FOUND; 3422 } 3423 3424 nwuf->size = 0; 3425 3426 for(k = 0; k < LM_NWUF_PATTERN_MASK_SIZE; k++) 3427 { 3428 nwuf->mask[k] = 0; 3429 } 3430 3431 for(k = 0; k < LM_NWUF_PATTERN_SIZE; k++) 3432 { 3433 nwuf->pattern[k] = 0xff; 3434 } 3435 3436 pdev->nwuf_list.cnt--; 3437 3438 return LM_STATUS_SUCCESS; 3439 } /* lm_del_nwuf */ 3440 3441 3442 3443 /******************************************************************************* 3444 * Description: 3445 * 3446 * Return: 3447 ******************************************************************************/ 3448 void 3449 lm_clear_nwuf( 3450 lm_device_t *pdev) 3451 { 3452 u32_t j; 3453 u32_t k; 3454 u32_t max_nwuf_cnt; 3455 3456 if(CHIP_NUM(pdev) == CHIP_NUM_5709) 3457 { 3458 max_nwuf_cnt = LM_MAX_NWUF_CNT_5709; 3459 } 3460 else 3461 { 3462 max_nwuf_cnt = LM_MAX_NWUF_CNT; 3463 } 3464 3465 for(j = 0; j < max_nwuf_cnt; j++) 3466 { 3467 pdev->nwuf_list.nwuf_arr[j].size = 0; 3468 3469 for(k = 0; k < LM_NWUF_PATTERN_MASK_SIZE; k++) 3470 { 3471 pdev->nwuf_list.nwuf_arr[j].mask[k] = 0; 3472 } 3473 3474 for(k = 0; k < LM_NWUF_PATTERN_SIZE; k++) 3475 { 3476 pdev->nwuf_list.nwuf_arr[j].pattern[k] = 0xff; 3477 } 3478 } 3479 3480 pdev->nwuf_list.cnt = 0; 3481 } /* lm_clear_nwuf */ 3482 3483 3484 3485 /******************************************************************************* 3486 * Description: 3487 * 3488 * Return: 3489 ******************************************************************************/ 3490 STATIC u32_t 3491 init_nwuf_5709( 3492 lm_device_t *pdev, 3493 lm_nwuf_list_t *nwuf_list) 3494 { 3495 lm_nwuf_t *nwuf; 3496 u16_t prev_val; 3497 u32_t nwuf_len; 3498 u32_t nwuf_cnt; 3499 u32_t offset; 3500 u8_t mask; 3501 u32_t val; 3502 u32_t idx; 3503 u8_t bit; 3504 u16_t pattern_size; 3505 u32_t nwuf_size[LM_MAX_NWUF_CNT_5709]; 3506 3507 DbgBreakIf(CHIP_NUM(pdev) != CHIP_NUM_5709); 3508 DbgBreakIf(LM_NWUF_PATTERN_SIZE > 128); 3509 DbgBreakIf(LM_MAX_NWUF_CNT_5709 > 8); 3510 3511 REG_WR(pdev, rpm.rpm_acpi_byte_enable_ctrl, RPM_ACPI_BYTE_ENABLE_CTRL_INIT); 3512 3513 for(idx = 0; idx < LM_MAX_NWUF_CNT_5709; idx++) 3514 { 3515 nwuf = &nwuf_list->nwuf_arr[idx]; 3516 nwuf_size[idx] = nwuf->size; 3517 } 3518 for(idx = 0; idx < 1000; idx++) 3519 { 3520 mm_wait(pdev, 5); 3521 3522 REG_RD(pdev, rpm.rpm_acpi_byte_enable_ctrl, &val); 3523 if((val & RPM_ACPI_BYTE_ENABLE_CTRL_INIT) == 0) 3524 { 3525 break; 3526 } 3527 } 3528 DbgBreakIf(val & RPM_ACPI_BYTE_ENABLE_CTRL_INIT); 3529 3530 val = 0; 3531 for(idx = 0; idx < 4; idx++) 3532 { 3533 nwuf = &nwuf_list->nwuf_arr[idx]; 3534 pattern_size = nwuf->size >>16; 3535 nwuf->size &= 0xffff; 3536 3537 DbgBreakIf(nwuf->size > LM_NWUF_PATTERN_MASK_SIZE); 3538 3539 if(nwuf->size == 0) 3540 { 3541 continue; 3542 } 3543 if (pattern_size) 3544 { 3545 val |= (pattern_size) << ((3 - idx) * 8); 3546 } 3547 else 3548 { 3549 val |= (nwuf->size * 8) << ((3 - idx) * 8); 3550 } 3551 } 3552 REG_WR(pdev, rpm.rpm_acpi_pattern_len0, val); 3553 3554 val = 0; 3555 for(idx = 4; idx < LM_MAX_NWUF_CNT_5709; idx++) 3556 { 3557 nwuf = &nwuf_list->nwuf_arr[idx]; 3558 pattern_size = nwuf->size >>16; 3559 nwuf->size &= 0xffff; 3560 3561 DbgBreakIf(nwuf->size > LM_NWUF_PATTERN_MASK_SIZE); 3562 3563 if(nwuf->size == 0) 3564 { 3565 continue; 3566 } 3567 3568 if (pattern_size) 3569 { 3570 val |= (pattern_size) << ((7 - idx) * 8); 3571 } 3572 else 3573 { 3574 val |= (nwuf->size * 8) << ((7 - idx) * 8); 3575 } 3576 3577 // old code val |= (nwuf->size * 8) << ((7 - idx) * 8); 3578 } 3579 REG_WR(pdev, rpm.rpm_acpi_pattern_len1, val); 3580 3581 for(offset = 0; offset < LM_NWUF_PATTERN_SIZE; offset++) 3582 { 3583 val = 0; 3584 3585 for(idx = 0; idx < LM_MAX_NWUF_CNT_5709; idx++) 3586 { 3587 nwuf = &nwuf_list->nwuf_arr[idx]; 3588 pattern_size = nwuf_size[idx]>>16; 3589 3590 if(nwuf->size == 0 || offset > nwuf->size * 8) 3591 { 3592 continue; 3593 } 3594 3595 mask = nwuf->mask[offset/8]; 3596 bit = offset % 8; 3597 3598 if(mask & (1 << bit)) 3599 { 3600 val |= 1 << idx; 3601 } 3602 } 3603 3604 REG_WR(pdev, rpm.rpm_acpi_data, val); 3605 3606 /* Perform the Write to the byte enable memory, The actual pattern 3607 * byte enables start from byte address 2. the first two bytes of 3608 * a packet are always 0 and inserted by EMAC to align the IP header 3609 * to 4-byte boudary. */ 3610 REG_WR( 3611 pdev, 3612 rpm.rpm_acpi_byte_enable_ctrl, 3613 RPM_ACPI_BYTE_ENABLE_CTRL_WR | offset); 3614 REG_RD(pdev, rpm.rpm_acpi_byte_enable_ctrl, &val); 3615 DbgBreakIf(val & RPM_ACPI_BYTE_ENABLE_CTRL_WR); 3616 } 3617 3618 nwuf_cnt = 0; 3619 3620 for(idx = 0; idx < LM_MAX_NWUF_CNT_5709; idx++) 3621 { 3622 REG_WR( 3623 pdev, 3624 rpm.rpm_acpi_pattern_ctrl, 3625 RPM_ACPI_PATTERN_CTRL_CRC_SM_CLR|idx); 3626 REG_RD(pdev, rpm.rpm_acpi_pattern_ctrl, &val); 3627 DbgBreakIf(val & RPM_ACPI_PATTERN_CTRL_CRC_SM_CLR); 3628 3629 nwuf = &nwuf_list->nwuf_arr[idx]; 3630 if(nwuf->size == 0) 3631 { 3632 continue; 3633 } 3634 pattern_size = nwuf_size[idx]>>16; 3635 3636 /* The CRC calculation is done on 64-bit data. So the length of the 3637 * pattern over which CRC needs to be calculated needs to be padded 3638 * by 0 to 7 bytes to make it 8 byte aligned. */ 3639 3640 if (pattern_size) 3641 { 3642 nwuf_len = pattern_size; 3643 } 3644 else 3645 { 3646 nwuf_len = (nwuf->size * 8); 3647 } 3648 nwuf_len += 2; /* 2-byte padding. */ 3649 nwuf_len = (nwuf_len + 3) & ~3; 3650 3651 prev_val = 0; 3652 3653 for(offset = 0; offset < nwuf_len; offset += 4) 3654 { 3655 val = 0; 3656 3657 for(bit = 0; bit < 4; bit++) 3658 { 3659 if (pattern_size) 3660 { 3661 if(offset < pattern_size) 3662 { 3663 mask = nwuf->mask[offset/8]; 3664 } 3665 else 3666 { 3667 mask = 0; 3668 } 3669 } 3670 else 3671 { 3672 if(offset < nwuf->size * 8) 3673 { 3674 mask = nwuf->mask[offset/8]; 3675 } 3676 else 3677 { 3678 mask = 0; 3679 } 3680 } 3681 if(mask & (1 << (bit + (offset % 8)))) 3682 { 3683 val |= nwuf->pattern[offset+bit] << ((3 - bit) * 8); 3684 } 3685 } 3686 3687 REG_WR(pdev, rpm.rpm_acpi_data, (prev_val << 16) | (val >> 16)); 3688 prev_val = (u16_t) val; 3689 3690 REG_WR( 3691 pdev, 3692 rpm.rpm_acpi_pattern_ctrl, 3693 RPM_ACPI_PATTERN_CTRL_WR | idx); 3694 REG_RD(pdev, rpm.rpm_acpi_pattern_ctrl, &val); 3695 DbgBreakIf(val & RPM_ACPI_PATTERN_CTRL_WR); 3696 } 3697 3698 nwuf_cnt++; 3699 } 3700 for(idx = 0; idx < LM_MAX_NWUF_CNT_5709; idx++) 3701 { 3702 nwuf = &nwuf_list->nwuf_arr[idx]; 3703 nwuf->size = nwuf_size[idx]; 3704 } 3705 3706 return nwuf_cnt; 3707 } /* init_nwuf_5709 */ 3708 3709 3710 3711 /******************************************************************************* 3712 * Description: 3713 * 3714 * Return: 3715 ******************************************************************************/ 3716 STATIC u32_t 3717 init_nwuf_5706( 3718 lm_device_t *pdev, 3719 lm_nwuf_list_t *nwuf_list) 3720 { 3721 typedef union _acpi_wol_pat_t 3722 { 3723 #if defined(LITTLE_ENDIAN) 3724 struct _acpi_wol_pat_as_u8_t 3725 { 3726 u8_t pat[7]; 3727 u8_t ena; 3728 } as_u8; 3729 3730 struct _acpi_wol_pat_as_u32_t 3731 { 3732 u32_t low; 3733 u32_t high; 3734 } as_u32; 3735 #elif defined(BIG_ENDIAN) 3736 struct _acpi_wol_pat_as_u8_t 3737 { 3738 u8_t ena; 3739 u8_t pat[7]; 3740 } as_u8; 3741 3742 struct _acpi_wol_pat_as_u32_t 3743 { 3744 u32_t high; 3745 u32_t low; 3746 } as_u32; 3747 #endif 3748 } acpi_wol_pat_t; 3749 3750 u32_t filler_pattern_idx; 3751 acpi_wol_pat_t wol_pat; 3752 u32_t pattern_cnt; 3753 u8_t val; 3754 u32_t j; 3755 u32_t k; 3756 u8_t idx; 3757 u32_t nwuf_size[LM_MAX_NWUF_CNT]; 3758 lm_nwuf_t *nwuf; 3759 3760 /* 3761 * 06/08 doesn't seem to have pattern size like those of 09 3762 */ 3763 for(idx = 0; idx < LM_MAX_NWUF_CNT; idx++) 3764 { 3765 nwuf = &nwuf_list->nwuf_arr[idx]; 3766 nwuf_size[idx] = nwuf->size; 3767 nwuf->size &= 0xffff; 3768 } 3769 3770 DbgBreakIf(LM_NWUF_PATTERN_SIZE > 128); 3771 DbgBreakIf(LM_MAX_NWUF_CNT > 7); 3772 DbgBreakIf(CHIP_NUM(pdev) != CHIP_NUM_5706 && 3773 CHIP_NUM(pdev) != CHIP_NUM_5708); 3774 3775 /* If a pattern is not present, we will fill the pattern buffer 3776 * with the pattern with this index. The pattern buffer cannot 3777 * have an empty pattern otherwise we will get a false detection. */ 3778 filler_pattern_idx = 0; 3779 3780 /* Find out the number of patterns. */ 3781 pattern_cnt = 0; 3782 for(k = 0; k < LM_MAX_NWUF_CNT; k++) 3783 { 3784 if(nwuf_list->nwuf_arr[k].size) 3785 { 3786 pattern_cnt++; 3787 filler_pattern_idx = k; 3788 } 3789 } 3790 3791 /* Program the pattern. */ 3792 for(j = 0; j < LM_NWUF_PATTERN_SIZE; j++) 3793 { 3794 wol_pat.as_u32.low = 0x0; 3795 wol_pat.as_u32.high = 0x0; 3796 3797 /* Build the enable bits. */ 3798 wol_pat.as_u8.ena = 0; 3799 for(k = 0; k < LM_MAX_NWUF_CNT; k++) 3800 { 3801 if(nwuf_list->nwuf_arr[k].size == 0) 3802 { 3803 val = nwuf_list->nwuf_arr[filler_pattern_idx].mask[j/8]; 3804 } 3805 else if((j/8) >= nwuf_list->nwuf_arr[k].size) 3806 { 3807 val = 0; 3808 } 3809 else 3810 { 3811 val = nwuf_list->nwuf_arr[k].mask[j/8]; 3812 } 3813 3814 /* Determine if a byte is enabled for comparision. */ 3815 if(val & (1 << (j % 8))) 3816 { 3817 wol_pat.as_u8.ena |= 1 << k; 3818 } 3819 } 3820 3821 DbgMessage1(pdev, VERBOSE, "%02x: ", j); 3822 3823 /* Enter the byte of each pattern that will be used for comparison. */ 3824 for(k = 0; k < LM_MAX_NWUF_CNT; k++) 3825 { 3826 /* Check to see if we are at the end of the pattern. 0xff 3827 * will terminate the pattern. If there is no pattern present 3828 * we cannot terminate with 0xff. */ 3829 if(nwuf_list->nwuf_arr[k].size == 0) 3830 { 3831 val = nwuf_list->nwuf_arr[filler_pattern_idx].pattern[j]; 3832 DbgMessage(pdev, VERBOSE, "xx "); 3833 } 3834 else if((j/8) >= nwuf_list->nwuf_arr[k].size) 3835 { 3836 val = 0xff; 3837 DbgMessage(pdev, VERBOSE, "ff "); 3838 } 3839 else 3840 { 3841 val = nwuf_list->nwuf_arr[k].pattern[j]; 3842 DbgMessage1(pdev, VERBOSE, "%02x ", val); 3843 } 3844 3845 /* Format of the ACPI_WOL pattern from low address to high on a 3846 * little endian system: 3847 * pat0_6 pat0_5 pat0_4 pat0_3 pat0_2 pat0_1 pat0_0 ena0 3848 * 3849 * on a big endian system: 3850 * ena0 pat0_0 pat0_1 pat0_2 pat0_3 pat0_4 pat0_5 pat0_6 */ 3851 #if defined(LITTLE_ENDIAN) 3852 wol_pat.as_u8.pat[6-k] = val; 3853 #elif defined(BIG_ENDIAN) 3854 wol_pat.as_u8.pat[k] = val; 3855 #endif 3856 } 3857 3858 DbgMessage2(pdev, VERBOSE, " %08x %08x\n", 3859 wol_pat.as_u32.high, wol_pat.as_u32.low); 3860 3861 /* Swap the even 64-bit word with the odd 64-bit word. This is 3862 * they way it works. Don't ask why. So the values written 3863 * to the header buffer looks as follows: 3864 * 0x0000: ena1 pat1_0 pat1_1 pat1_2 3865 * 0x0004: pat1_3 pat1_4 pat1_5 pat1_6 3866 * 0x0008: ena0 pat0_0 pat0_1 pat0_2 3867 * 0x000c: pat0_3 pat0_4 pat0_5 pat0_6 3868 * 0x0010: ena3 pat3_0 pat3_1 pat3_2 3869 * 0x0014: pat3_3 pat3_4 pat3_5 pat3_6 3870 * 0x0018: ena2 pat2_0 pat2_1 pat2_2 3871 * 0x001c: pat2_3 pat2_4 pat2_5 pat2_6 */ 3872 if(j % 2) 3873 { 3874 REG_WR_IND( 3875 pdev, 3876 OFFSETOF(reg_space_t, tas.tas_thbuf[(j-1) * 2]), 3877 wol_pat.as_u32.high); 3878 REG_WR_IND( 3879 pdev, 3880 OFFSETOF(reg_space_t, tas.tas_thbuf[(j-1) * 2 + 1]), 3881 wol_pat.as_u32.low); 3882 } 3883 else 3884 { 3885 REG_WR_IND( 3886 pdev, 3887 OFFSETOF(reg_space_t, tas.tas_thbuf[(j+1) * 2]), 3888 wol_pat.as_u32.high); 3889 REG_WR_IND( 3890 pdev, 3891 OFFSETOF(reg_space_t, tas.tas_thbuf[(j+1) * 2 + 1]), 3892 wol_pat.as_u32.low); 3893 } 3894 } 3895 3896 for(idx = 0; idx < LM_MAX_NWUF_CNT; idx++) 3897 { 3898 nwuf = &nwuf_list->nwuf_arr[idx]; 3899 nwuf->size = nwuf_size[idx]; 3900 } 3901 3902 return pattern_cnt; 3903 } /* init_nwuf_5706 */ 3904 3905 3906 3907 /******************************************************************************* 3908 * Description: 3909 * 3910 * Return: 3911 ******************************************************************************/ 3912 STATIC u32_t 3913 init_nwuf( 3914 lm_device_t *pdev, 3915 lm_nwuf_list_t *nwuf_list) 3916 { 3917 u32_t nwuf_cnt; 3918 3919 if(CHIP_NUM(pdev) == CHIP_NUM_5706 || CHIP_NUM(pdev) == CHIP_NUM_5708) 3920 { 3921 nwuf_cnt = init_nwuf_5706(pdev, nwuf_list); 3922 } 3923 else 3924 { 3925 nwuf_cnt = init_nwuf_5709(pdev, nwuf_list); 3926 } 3927 3928 return nwuf_cnt; 3929 } /* init_nwuf */ 3930 3931 3932 3933 /******************************************************************************* 3934 * Description: 3935 * 3936 * Return: 3937 ******************************************************************************/ 3938 STATIC void 3939 set_d0_power_state( 3940 lm_device_t *pdev, 3941 u8_t set_pci_pm) 3942 { 3943 u32_t val; 3944 u32_t idx; 3945 3946 /* This step should be done by the OS or the caller. Windows is 3947 * already doing this. */ 3948 if(set_pci_pm) 3949 { 3950 /* Set the device to D0 state. If a device is already in D3 state, 3951 * we will not be able to read the PCICFG_PM_CSR register using the 3952 * PCI memory command, we need to use config access here. */ 3953 (void) mm_read_pci( 3954 pdev, 3955 OFFSETOF(reg_space_t, pci_config.pcicfg_pm_csr), 3956 &val); 3957 3958 /* Set the device to D0 state. This may be already done by the OS. */ 3959 val &= ~PCICFG_PM_CSR_STATE; 3960 val |= PCICFG_PM_CSR_STATE_D0 | PCICFG_PM_CSR_PME_STATUS; 3961 3962 (void) mm_write_pci( 3963 pdev, 3964 OFFSETOF(reg_space_t, pci_config.pcicfg_pm_csr), 3965 val); 3966 } 3967 3968 /* With 5706_A1, the chip gets a reset coming out of D3. Wait 3969 * for the boot to code finish running before we continue. Without 3970 * this wait, we could run into lockup or the PHY may not work. */ 3971 if(CHIP_ID(pdev) == CHIP_ID_5706_A1) 3972 { 3973 for(idx = 0; idx < 1000; idx++) 3974 { 3975 mm_wait(pdev, 15); 3976 } 3977 } 3978 3979 /* Clear the ACPI_RCVD and MPKT_RCVD bits and disable magic packet. */ 3980 REG_RD(pdev, emac.emac_mode, &val); 3981 val |= EMAC_MODE_MPKT_RCVD | EMAC_MODE_ACPI_RCVD; 3982 val &= ~EMAC_MODE_MPKT; 3983 REG_WR(pdev, emac.emac_mode, val); 3984 3985 /* Disable interesting packet detection. */ 3986 REG_RD(pdev, rpm.rpm_config, &val); 3987 val &= ~RPM_CONFIG_ACPI_ENA; 3988 REG_WR(pdev, rpm.rpm_config, val); 3989 } /* set_d0_power_state */ 3990 3991 3992 3993 /******************************************************************************* 3994 * Description: 3995 * 3996 * Return: 3997 ******************************************************************************/ 3998 STATIC void 3999 set_d3_power_state( 4000 lm_device_t *pdev, 4001 lm_wake_up_mode_t wake_up_mode, 4002 u8_t set_pci_pm) 4003 { 4004 u32_t fw_timed_out; 4005 u32_t reset_reason; 4006 u32_t gpio_pin; 4007 u32_t val; 4008 u32_t cnt; 4009 4010 /* Set up magic and interesting packet detection. */ 4011 if(wake_up_mode & (LM_WAKE_UP_MODE_MAGIC_PACKET | LM_WAKE_UP_MODE_NWUF)) 4012 { 4013 /* Enable magic packet detection. */ 4014 REG_RD(pdev, emac.emac_mode, &val); 4015 if(wake_up_mode & LM_WAKE_UP_MODE_MAGIC_PACKET) 4016 { 4017 val |= EMAC_MODE_MPKT; 4018 } 4019 else 4020 { 4021 val &= ~EMAC_MODE_MPKT; 4022 } 4023 4024 /* Enable port mode. */ 4025 val &= ~EMAC_MODE_PORT; 4026 if(CHIP_REV(pdev) == CHIP_REV_FPGA || CHIP_REV(pdev) == CHIP_REV_IKOS) 4027 { 4028 /* IKOS or FPGA always run in GMII mode even if its actual 4029 * link speed is 10mb or 100mb. */ 4030 val |= EMAC_MODE_PORT_GMII; 4031 } 4032 else 4033 { 4034 val |= EMAC_MODE_PORT_MII; 4035 } 4036 val |= EMAC_MODE_MPKT_RCVD | EMAC_MODE_ACPI_RCVD; 4037 4038 REG_WR(pdev, emac.emac_mode, val); 4039 4040 /* Set up the receive mask. */ 4041 (void) lm_set_rx_mask( 4042 pdev, 4043 RX_FILTER_USER_IDX0, 4044 LM_RX_MASK_ACCEPT_UNICAST | 4045 LM_RX_MASK_ACCEPT_ALL_MULTICAST | 4046 LM_RX_MASK_ACCEPT_BROADCAST); 4047 4048 /* The first four address slots are use for magic packet detection. 4049 * we need to initialize all four address slots. */ 4050 for(cnt = 0; cnt < 4; cnt++) 4051 { 4052 (void) lm_set_mac_addr(pdev, cnt, pdev->params.mac_addr); 4053 } 4054 4055 /* Need to enable EMAC and RPM for WOL. */ 4056 REG_WR( 4057 pdev, 4058 misc.misc_enable_set_bits, 4059 MISC_ENABLE_SET_BITS_RX_PARSER_MAC_ENABLE | 4060 MISC_ENABLE_SET_BITS_TX_HEADER_Q_ENABLE | 4061 MISC_ENABLE_SET_BITS_EMAC_ENABLE); 4062 4063 /* Enable interesting packet detection. This must be done after 4064 * the necessary blocks are enabled, otherwise we may wake-up on 4065 * a bogus first packet. Need to document this in prm. */ 4066 REG_RD(pdev, rpm.rpm_config, &val); 4067 if(wake_up_mode & LM_WAKE_UP_MODE_NWUF) 4068 { 4069 REG_WR(pdev, rpm.rpm_config, val & ~RPM_CONFIG_ACPI_ENA); 4070 4071 /* Also need to be documented in the prm - to prevent a false 4072 * detection, we need to disable ACP_EN if there is no pattern 4073 * programmed. There is no way of preventing false detection 4074 * by intializing the pattern buffer a certain way. */ 4075 if(init_nwuf(pdev, &pdev->nwuf_list)) 4076 { 4077 val |= RPM_CONFIG_ACPI_ENA; 4078 } 4079 else 4080 { 4081 val &= ~RPM_CONFIG_ACPI_ENA; 4082 } 4083 } 4084 else 4085 { 4086 val &= ~RPM_CONFIG_ACPI_ENA; 4087 } 4088 REG_WR(pdev, rpm.rpm_config, val); 4089 4090 /* xinan requires rbuf to be enabled. enabling it for teton 4091 * does not hurt. */ 4092 REG_WR( 4093 pdev, 4094 misc.misc_enable_set_bits, 4095 MISC_ENABLE_SET_BITS_RX_MBUF_ENABLE); 4096 4097 reset_reason = LM_REASON_WOL_SUSPEND; 4098 } 4099 else 4100 { 4101 reset_reason = LM_REASON_NO_WOL_SUSPEND; 4102 } 4103 4104 /* Allow the firmware to make any final changes to the chip before 4105 * we go into D3 mode. The timeout period is longer because the 4106 * firwmare could take more time to download management firmware 4107 * which occurs during this stage of the reset. */ 4108 fw_timed_out = fw_reset_sync( 4109 pdev, 4110 reset_reason, 4111 DRV_MSG_DATA_WAIT3, 4112 FW_ACK_TIME_OUT_MS*1000 * 3); 4113 4114 /* If the firmware is not running, we have to switch to vaux power, 4115 * otherwise let the firmware do it. */ 4116 if(fw_timed_out) 4117 { 4118 /* Power down the PHY. */ 4119 if(pdev->params.enable_remote_phy == FALSE) 4120 { 4121 if(CHIP_REV(pdev) != CHIP_REV_FPGA && 4122 CHIP_REV(pdev) != CHIP_REV_IKOS) 4123 { 4124 (void) lm_mwrite( 4125 pdev, 4126 pdev->params.phy_addr, 4127 0x1c, 4128 0xa821); 4129 } 4130 } 4131 4132 /* Minimum core clock for a particular link. 4133 * 10Mb core_clk = 6.25Mhz 4134 * 100Mb core_clk = 12Mhz 4135 * 1Gb core_clk = 100Mhz (use PLL) 4136 * 4137 * The driver is configured to autoneg to 10/100Mb for WOL mode. So 4138 * the core clock needs to be configured to 12Mhz. */ 4139 REG_RD(pdev, misc.misc_clock_control_bits, &val); 4140 val &= ~(MISC_CLOCK_CONTROL_BITS_CORE_CLK_DISABLE | 4141 MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT | 4142 MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_TE); 4143 4144 /* Select the 12.5m alt clock. */ 4145 REG_WR( 4146 pdev, 4147 misc.misc_clock_control_bits, 4148 MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_12_TE | val); 4149 4150 /* Switch to the alt clock. */ 4151 REG_WR( 4152 pdev, 4153 misc.misc_clock_control_bits, 4154 MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_12_TE | 4155 MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT | 4156 val); 4157 4158 /* Disable core clock to non-wol blocks. */ 4159 REG_WR( 4160 pdev, 4161 misc.misc_clock_control_bits, 4162 MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_12_TE | 4163 MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT | 4164 MISC_CLOCK_CONTROL_BITS_CORE_CLK_DISABLE | 4165 val); 4166 4167 gpio_pin = 1 << 2; /* GPIO 2 */ 4168 4169 /* Switch to vaux power by bring GPIO2 to low. */ 4170 REG_RD(pdev, misc.misc_spio, &val); 4171 val &= ~(gpio_pin << 24); /* use this gpio as output. */ 4172 val |= gpio_pin << 16; /* clear the gpio. */ 4173 REG_WR(pdev, misc.misc_spio, val); 4174 4175 /* This step should be done by the OS or the caller. Windows is 4176 * already doing this. */ 4177 if(set_pci_pm) 4178 { 4179 /* Set the device to D3 state. */ 4180 REG_RD_OFFSET( 4181 pdev, 4182 OFFSETOF(reg_space_t, pci_config.pcicfg_pm_csr), 4183 &val); 4184 4185 val &= ~PCICFG_PM_CSR_STATE; 4186 val |= PCICFG_PM_CSR_STATE_D3_HOT; 4187 4188 REG_WR_OFFSET( 4189 pdev, 4190 OFFSETOF(reg_space_t, pci_config.pcicfg_pm_csr), 4191 val); 4192 } 4193 } 4194 } /* set_d3_power_state */ 4195 4196 4197 4198 /******************************************************************************* 4199 * Description: 4200 * 4201 * Return: 4202 ******************************************************************************/ 4203 void 4204 lm_set_power_state( 4205 lm_device_t *pdev, 4206 lm_power_state_t power_state, 4207 lm_wake_up_mode_t wake_up_mode, /* Valid when power_state is D3. */ 4208 u8_t set_pci_pm) 4209 { 4210 if(power_state == LM_POWER_STATE_D0) 4211 { 4212 set_d0_power_state(pdev, set_pci_pm); 4213 } 4214 else 4215 { 4216 set_d3_power_state(pdev, wake_up_mode, set_pci_pm); 4217 } 4218 } /* lm_set_power_state */ 4219 4220 4221 4222 #ifndef EXCLUDE_KQE_SUPPORT 4223 /******************************************************************************* 4224 * Description: 4225 * 4226 * Return: 4227 ******************************************************************************/ 4228 u32_t 4229 lm_submit_kernel_wqes( 4230 lm_device_t *pdev, 4231 kwqe_t *wqes[], 4232 u32_t num_wqes) 4233 { 4234 kwqe_t *prod_qe; 4235 u16_t prod_idx; 4236 u32_t qe_cnt; 4237 4238 if(num_wqes > pdev->kq_info.kwqe_left) 4239 { 4240 pdev->kq_info.no_kwq_bd_left++; 4241 4242 return 0; 4243 } 4244 4245 pdev->kq_info.kwqe_left -= num_wqes; 4246 4247 prod_qe = pdev->kq_info.kwq_prod_qe; 4248 prod_idx = pdev->kq_info.kwq_prod_idx; 4249 4250 qe_cnt = num_wqes; 4251 while(qe_cnt) 4252 { 4253 *prod_qe = *(*wqes); 4254 4255 if(prod_qe == pdev->kq_info.kwq_last_qe) 4256 { 4257 prod_qe = pdev->kq_info.kwq_virt; 4258 } 4259 else 4260 { 4261 prod_qe++; 4262 } 4263 4264 wqes++; 4265 prod_idx++; 4266 qe_cnt--; 4267 } 4268 4269 pdev->kq_info.kwq_prod_qe = prod_qe; 4270 pdev->kq_info.kwq_prod_idx = prod_idx; 4271 4272 MBQ_WR16( 4273 pdev, 4274 GET_CID(pdev->kq_info.kwq_cid_addr), 4275 OFFSETOF(krnlq_context_t, krnlq_host_qidx), 4276 prod_idx); 4277 4278 return num_wqes; 4279 } /* lm_submit_kernel_wqes */ 4280 #endif /* EXCLUDE_KQE_SUPPORT */ 4281 4282 4283 4284 /******************************************************************************* 4285 * Description: 4286 * 4287 * Return: 4288 ******************************************************************************/ 4289 lm_interrupt_status_t 4290 lm_get_interrupt_status( 4291 lm_device_t *pdev) 4292 { 4293 lm_interrupt_status_t intr_status; 4294 u32_t deasserted_attns; 4295 u32_t asserted_attns; 4296 lm_rx_chain_t *rxq; 4297 lm_tx_chain_t *txq; 4298 u16_t hw_con_idx; 4299 u32_t val; 4300 u32_t idx; 4301 4302 intr_status = LM_NO_EVENT_ACTIVE; 4303 4304 /* Determine link change status. */ 4305 if(pdev->params.link_chng_mode == LINK_CHNG_MODE_USE_STATUS_REG) 4306 { 4307 REG_RD(pdev, emac.emac_status, &val); 4308 if(pdev->params.phy_int_mode == PHY_INT_MODE_MI_INTERRUPT) 4309 { 4310 if(val & EMAC_STATUS_MI_INT) 4311 { 4312 intr_status |= LM_PHY_EVENT_ACTIVE; 4313 } 4314 } 4315 else if(val & EMAC_STATUS_LINK_CHANGE) 4316 { 4317 intr_status |= LM_PHY_EVENT_ACTIVE; 4318 } 4319 4320 GET_ATTN_CHNG_BITS(pdev, &asserted_attns, &deasserted_attns); 4321 } 4322 else 4323 { 4324 GET_ATTN_CHNG_BITS(pdev, &asserted_attns, &deasserted_attns); 4325 4326 if(asserted_attns & STATUS_ATTN_BITS_LINK_STATE) 4327 { 4328 intr_status |= LM_PHY_EVENT_ACTIVE; 4329 } 4330 else if(deasserted_attns & STATUS_ATTN_BITS_LINK_STATE) 4331 { 4332 intr_status |= LM_PHY_EVENT_ACTIVE; 4333 } 4334 } 4335 4336 /* Get driver pulse event. MCP uses the TIMER_ABORT attention to 4337 * signal to the driver to write a driver pulse to the firmware. */ 4338 if((asserted_attns & STATUS_ATTN_BITS_TIMER_ABORT) || 4339 (deasserted_attns & STATUS_ATTN_BITS_TIMER_ABORT)) 4340 { 4341 if(pdev->params.enable_remote_phy) 4342 { 4343 REG_RD_IND( 4344 pdev, 4345 pdev->hw_info.shmem_base + 4346 OFFSETOF(shmem_region_t, fw_evt_mb.fw_evt_code_mb), 4347 &val); 4348 4349 if(val == 0) 4350 { 4351 intr_status |= LM_KNOCK_KNOCK_EVENT; 4352 } 4353 else if(val == FW_EVT_CODE_LINK_STATUS_CHANGE_EVENT) 4354 { 4355 intr_status |= LM_PHY_EVENT_ACTIVE; 4356 } 4357 else 4358 { 4359 DbgBreakMsg("not a valid fw event.\n"); 4360 } 4361 } 4362 else 4363 { 4364 intr_status |= LM_KNOCK_KNOCK_EVENT; 4365 } 4366 4367 if(asserted_attns & STATUS_ATTN_BITS_TIMER_ABORT) 4368 { 4369 REG_WR( 4370 pdev, 4371 pci_config.pcicfg_status_bit_set_cmd, 4372 asserted_attns & STATUS_ATTN_BITS_TIMER_ABORT); 4373 } 4374 else 4375 { 4376 REG_WR( 4377 pdev, 4378 pci_config.pcicfg_status_bit_clear_cmd, 4379 deasserted_attns & STATUS_ATTN_BITS_TIMER_ABORT); 4380 } 4381 } 4382 4383 /* get l2 tx events. */ 4384 for(idx = 0; idx < pdev->tx_info.num_txq; idx++) 4385 { 4386 txq = &pdev->tx_info.chain[idx]; 4387 4388 hw_con_idx = *txq->hw_con_idx_ptr; 4389 if((hw_con_idx & MAX_BD_PER_PAGE) == MAX_BD_PER_PAGE) 4390 { 4391 hw_con_idx++; 4392 } 4393 4394 if(hw_con_idx != txq->con_idx) 4395 { 4396 intr_status |= LM_TX0_EVENT_ACTIVE << txq->idx; 4397 } 4398 } 4399 4400 /* get l2 rx events. */ 4401 for(idx = 0; idx < pdev->rx_info.num_rxq; idx++) 4402 { 4403 rxq = &pdev->rx_info.chain[idx]; 4404 4405 hw_con_idx = *rxq->hw_con_idx_ptr; 4406 if((hw_con_idx & MAX_BD_PER_PAGE) == MAX_BD_PER_PAGE) 4407 { 4408 hw_con_idx++; 4409 } 4410 4411 if(hw_con_idx != rxq->con_idx) 4412 { 4413 intr_status |= LM_RX0_EVENT_ACTIVE << rxq->idx; 4414 } 4415 } 4416 4417 #ifndef EXCLUDE_KQE_SUPPORT 4418 if(CHIP_NUM(pdev) == CHIP_NUM_5706 || CHIP_NUM(pdev) == CHIP_NUM_5708) 4419 { 4420 /* HC install problem: as a workaround, rx_quick_consumer_index15 4421 * is high jacked for use as cmd_con_idx. The original cmd_con_idx 4422 * is not used. */ 4423 if(pdev->kq_info.kwq_con_idx != 4424 pdev->vars.status_virt->deflt.status_rx_quick_consumer_index15) 4425 { 4426 intr_status |= LM_KWQ_EVENT_ACTIVE; 4427 } 4428 } 4429 else 4430 { 4431 if(pdev->kq_info.kwq_con_idx != 4432 pdev->vars.status_virt->deflt.status_cmd_consumer_index) 4433 { 4434 intr_status |= LM_KWQ_EVENT_ACTIVE; 4435 } 4436 } 4437 4438 if(pdev->kq_info.kcq_con_idx != 4439 pdev->vars.status_virt->deflt.status_completion_producer_index) 4440 { 4441 intr_status |= LM_KCQ_EVENT_ACTIVE; 4442 } 4443 #endif 4444 4445 #if INCLUDE_OFLD_SUPPORT 4446 else if(pdev->params.hcopy_desc_cnt) 4447 { 4448 if(pdev->ofld.hcopy_chain.con_idx != 4449 *(pdev->ofld.hcopy_chain.hw_con_idx_ptr)) 4450 { 4451 intr_status |= LM_KCQ_EVENT_ACTIVE; 4452 } 4453 } 4454 #endif 4455 4456 return intr_status; 4457 } /* lm_get_interrupt_status */ 4458 4459 4460 4461 #ifndef EXCLUDE_KQE_SUPPORT 4462 /******************************************************************************* 4463 * Description: 4464 * 4465 * Return: 4466 ******************************************************************************/ 4467 void 4468 lm_ack_completed_wqes( 4469 lm_device_t *pdev) 4470 { 4471 u16_t new_con_idx; 4472 kwqe_t *con_qe; 4473 u16_t num_wqes; 4474 u16_t con_idx; 4475 4476 /* HC install problem: as a workaround, rx_quick_consumer_index15 4477 * is high jacked for use as cmd_con_idx. The original cmd_con_idx 4478 * is not used. */ 4479 if(CHIP_NUM(pdev) == CHIP_NUM_5706 || CHIP_NUM(pdev) == CHIP_NUM_5708) 4480 { 4481 new_con_idx = 4482 pdev->vars.status_virt->deflt.status_rx_quick_consumer_index15; 4483 } 4484 else 4485 { 4486 new_con_idx = pdev->vars.status_virt->deflt.status_cmd_consumer_index; 4487 } 4488 4489 num_wqes = (u16_t) S16_SUB(new_con_idx, pdev->kq_info.kwq_con_idx); 4490 pdev->kq_info.kwqe_left += num_wqes; 4491 4492 con_idx = new_con_idx; 4493 con_qe = pdev->kq_info.kwq_con_qe + num_wqes; 4494 4495 /* Check for con_qe wrap around. */ 4496 if((u8_t *) con_qe > (u8_t *) pdev->kq_info.kwq_last_qe) 4497 { 4498 con_qe = (kwqe_t *) ((u8_t *) pdev->kq_info.kwq_virt + 4499 ((u8_t *) con_qe - (u8_t *) pdev->kq_info.kwq_last_qe)); 4500 con_qe--; 4501 } 4502 4503 pdev->kq_info.kwq_con_idx = con_idx; 4504 pdev->kq_info.kwq_con_qe = con_qe; 4505 4506 /* Make sure the con_qe and con_idx are consistent. */ 4507 DbgBreakIf(((((u8_t *) con_qe - (u8_t *) pdev->kq_info.kwq_virt) / 4508 sizeof(kwqe_t)) & 0x7f) != (con_idx & 0x7f)); 4509 4510 #if DBG 4511 /* Make sure all the kwqes are accounted for. */ 4512 if(S16_SUB(pdev->kq_info.kwq_prod_idx, con_idx) >= 0) 4513 { 4514 num_wqes = pdev->kq_info.kwqe_left + 4515 (u32_t) S16_SUB(pdev->kq_info.kwq_prod_idx, con_idx); 4516 } 4517 else 4518 { 4519 num_wqes = pdev->kq_info.kwqe_left + 0x10000 - con_idx + 4520 pdev->kq_info.kwq_prod_idx; 4521 } 4522 4523 DbgBreakIf(num_wqes != (LM_PAGE_SIZE/sizeof(kwqe_t)) * 4524 pdev->params.kwq_page_cnt - 1); 4525 #endif 4526 } /* lm_ack_completed_wqes */ 4527 4528 4529 4530 /******************************************************************************* 4531 * Description: 4532 * 4533 * Return: 4534 ******************************************************************************/ 4535 u32_t 4536 lm_get_kernel_cqes( 4537 lm_device_t *pdev, 4538 kcqe_t *cqe_ptr[], 4539 u32_t ptr_cnt) 4540 { 4541 kcqe_t *con_qe; 4542 u16_t prod_idx; 4543 u32_t num_cqes; 4544 u16_t con_idx; 4545 4546 DbgMessage(pdev, VERBOSEint, "### lm_get_kernel_cqes\n"); 4547 4548 con_idx = pdev->kq_info.kcq_con_idx; 4549 con_qe = pdev->kq_info.kcq_con_qe; 4550 4551 DbgBreakIf(((((u8_t *) con_qe - (u8_t *) pdev->kq_info.kcq_virt) / 4552 sizeof(kcqe_t)) & 0x7f) != (con_idx & 0x7f)); 4553 4554 num_cqes = 0; 4555 prod_idx = pdev->vars.status_virt->deflt.status_completion_producer_index; 4556 4557 while(con_idx != prod_idx && num_cqes != ptr_cnt) 4558 { 4559 *cqe_ptr = con_qe; 4560 cqe_ptr++; 4561 num_cqes++; 4562 con_idx++; 4563 4564 if(con_qe == pdev->kq_info.kcq_last_qe) 4565 { 4566 con_qe = pdev->kq_info.kcq_virt; 4567 } 4568 else 4569 { 4570 con_qe++; 4571 } 4572 4573 prod_idx = 4574 pdev->vars.status_virt->deflt.status_completion_producer_index; 4575 } 4576 4577 /* Make sure the last entry in the array does not have the 'next' 4578 * bit set. We want to ensure the array contains all the cqes 4579 * for a completion. 4580 * 4581 * This piece of code also takes care of the case where a completion 4582 * spans multiple kcqes and not all the kcqes have been dma'd to 4583 * the host. For example, if a completion consists of A, B, C, and D 4584 * kcqes. The status block may tell us A and B have been dma'd. In 4585 * this case, we don't want to return kcqes A and B in the array. */ 4586 cqe_ptr--; 4587 while(num_cqes && ((*cqe_ptr)->kcqe_flags & KCQE_FLAGS_NEXT)) 4588 { 4589 num_cqes--; 4590 cqe_ptr--; 4591 } 4592 4593 DbgBreakIf(num_cqes == 0); 4594 4595 return num_cqes; 4596 } /* lm_get_kernel_cqes */ 4597 4598 4599 4600 /******************************************************************************* 4601 * Description: 4602 * 4603 * Return: 4604 ******************************************************************************/ 4605 u8_t 4606 lm_ack_kernel_cqes( 4607 lm_device_t *pdev, 4608 u32_t num_cqes) 4609 { 4610 kcqe_t *con_qe; 4611 u16_t prod_idx; 4612 u16_t con_idx; 4613 4614 DbgMessage(pdev, VERBOSEint, "### lm_ack_kernel_cqes\n"); 4615 4616 con_idx = pdev->kq_info.kcq_con_idx; 4617 4618 if(num_cqes) 4619 { 4620 /* Advance the consumer index and the con_qe pointer */ 4621 con_idx += (u16_t) num_cqes; 4622 con_qe = pdev->kq_info.kcq_con_qe + num_cqes; 4623 4624 /* Check for con_qe wrap around. */ 4625 if((u8_t *) con_qe > (u8_t *) pdev->kq_info.kcq_last_qe) 4626 { 4627 con_qe = (kcqe_t *) ((u8_t *) pdev->kq_info.kcq_virt + 4628 ((u8_t *) con_qe - (u8_t *) pdev->kq_info.kcq_last_qe)); 4629 con_qe--; 4630 } 4631 4632 pdev->kq_info.kcq_con_idx = con_idx; 4633 pdev->kq_info.kcq_con_qe = con_qe; 4634 4635 /* Don't acknowledge the last 'kcq_history_size' entries so the 4636 * chip will not over write them with new entries. We are doing 4637 * this to have a history of the kcq entries for debugging. */ 4638 if(pdev->params.kcq_history_size) 4639 { 4640 /* The con_idx should always be ahead of history_kcq_con_idx. */ 4641 DbgBreakIf(S16_SUB(con_idx, pdev->kq_info.history_kcq_con_idx) < 0); 4642 4643 /* Number of entries between con_idx and history_kcq_con_idx. */ 4644 num_cqes = (u32_t) S16_SUB( 4645 con_idx, 4646 pdev->kq_info.history_kcq_con_idx); 4647 4648 /* Don't advance the consumer index if the number of history 4649 * entries is less than 'kcq_history_size'. */ 4650 if(num_cqes >= pdev->params.kcq_history_size) 4651 { 4652 /* Make sure we will have at most kcq_history_size entires. */ 4653 num_cqes -= pdev->params.kcq_history_size; 4654 4655 DbgBreakIf(num_cqes > pdev->params.kcq_history_size); 4656 4657 /* Advance the consumer index and the con_qe pointer */ 4658 pdev->kq_info.history_kcq_con_idx += (u16_t) num_cqes; 4659 con_qe = pdev->kq_info.history_kcq_con_qe + num_cqes; 4660 4661 /* Check for con_qe wrap around. */ 4662 if((u8_t *) con_qe > (u8_t *) pdev->kq_info.kcq_last_qe) 4663 { 4664 con_qe = (kcqe_t *) ((u8_t *) pdev->kq_info.kcq_virt + 4665 ((u8_t *) con_qe - 4666 (u8_t *) pdev->kq_info.kcq_last_qe)); 4667 con_qe--; 4668 } 4669 pdev->kq_info.history_kcq_con_qe = con_qe; 4670 4671 MBQ_WR16( 4672 pdev, 4673 GET_CID(pdev->kq_info.kcq_cid_addr), 4674 OFFSETOF(krnlq_context_t, krnlq_host_qidx), 4675 pdev->kq_info.history_kcq_con_idx); 4676 } 4677 } 4678 else 4679 { 4680 MBQ_WR16( 4681 pdev, 4682 GET_CID(pdev->kq_info.kcq_cid_addr), 4683 OFFSETOF(krnlq_context_t, krnlq_host_qidx), 4684 con_idx); 4685 } 4686 } 4687 4688 prod_idx = pdev->vars.status_virt->deflt.status_completion_producer_index; 4689 4690 DbgBreakIf(S16_SUB(prod_idx, con_idx) < 0); 4691 4692 return con_idx != prod_idx; 4693 } /* lm_ack_kernel_cqes */ 4694 #endif /* EXCLUDE_KQE_SUPPORT */ 4695 4696 4697 4698 #ifndef EXCLUDE_RSS_SUPPORT 4699 #if RSS_LOOKUP_TABLE_WA 4700 /******************************************************************************* 4701 * Description: 4702 * 4703 * Return: 4704 ******************************************************************************/ 4705 u64_t 4706 rss_f64( 4707 u8_t* key, 4708 u8_t s, 4709 u8_t e 4710 ) 4711 { 4712 u64_t f; 4713 4714 for( f=0; s<=e; ++s ) 4715 { 4716 f = (f << 8); 4717 f |= key[s]; 4718 } 4719 4720 return f; 4721 } 4722 4723 4724 4725 /******************************************************************************* 4726 * Description: 4727 * 4728 * Return: 4729 ******************************************************************************/ 4730 u32_t 4731 rss_hash_byte( 4732 u8_t* key, 4733 u8_t byte, 4734 u8_t s, 4735 u8_t e, 4736 u32_t rst 4737 ) 4738 { 4739 u8_t i; 4740 u64_t key_msb; 4741 4742 key_msb = rss_f64(key, s,e); 4743 4744 for( i=0x80; i!=0; i>>=1 ) 4745 { 4746 if( i & byte ) 4747 { 4748 u32_t k; 4749 4750 k = (u32_t)(key_msb >> 32); 4751 rst ^= k; 4752 } 4753 key_msb = (key_msb << 1); 4754 } 4755 4756 return rst; 4757 } 4758 4759 4760 4761 /******************************************************************************* 4762 * Description: 4763 * 4764 * Return: 4765 ******************************************************************************/ 4766 void 4767 rss_gen_one_table( 4768 u8_t* key, 4769 u8_t s, 4770 u8_t e, 4771 u32_t* gtbl 4772 ) 4773 { 4774 u32_t i; 4775 4776 for( i = 0; i < 256; ++i ) 4777 { 4778 gtbl[i] = rss_hash_byte( key, (u8_t)i, s, e, 0 ); 4779 } 4780 } 4781 4782 4783 4784 /******************************************************************************* 4785 * Description: 4786 * 4787 * Return: 4788 ******************************************************************************/ 4789 void 4790 rss_gen_tables( 4791 u8_t* key, 4792 u32_t* tables 4793 ) 4794 { 4795 u8_t t; 4796 4797 for( t = 0; t < 12; ++t ) 4798 { 4799 rss_gen_one_table( key, t, (u8_t)(t+7), tables ); 4800 tables += 256; 4801 } 4802 } 4803 #endif 4804 4805 4806 #ifndef LM_NON_LEGACY_MODE_SUPPORT 4807 /******************************************************************************* 4808 * Description: 4809 * 4810 * Return: 4811 ******************************************************************************/ 4812 lm_status_t 4813 lm_enable_rss( 4814 lm_device_t *pdev, 4815 lm_rss_hash_t hash_type, 4816 u8_t *indirection_table, 4817 u32_t table_size, 4818 u8_t *hash_key, 4819 u32_t key_size) 4820 { 4821 l2_kwqe_rss_table_update_t *rss_update; 4822 u8_t rss_key[RSS_HASH_KEY_SIZE]; 4823 lm_address_t rss_table_phy; 4824 u8_t *rss_table_virt; 4825 kwqe_t *prod_qe; 4826 u16_t prod_idx; 4827 u32_t idx; 4828 u32_t val; 4829 4830 if(pdev->kq_info.kwqe_left < 2) 4831 { 4832 pdev->kq_info.no_kwq_bd_left++; 4833 return LM_STATUS_RESOURCE; 4834 } 4835 4836 pdev->kq_info.kwqe_left -= 2; 4837 4838 DbgBreakIf(key_size > RSS_HASH_KEY_SIZE); 4839 4840 /* Initialize the rss key array. */ 4841 if(key_size > RSS_HASH_KEY_SIZE) 4842 { 4843 key_size = RSS_HASH_KEY_SIZE; 4844 } 4845 4846 for(idx = 0; idx < key_size; idx++) 4847 { 4848 rss_key[idx] = hash_key[idx]; 4849 } 4850 4851 for(idx = key_size; idx < RSS_HASH_KEY_SIZE; idx++) 4852 { 4853 rss_key[idx] = 0; 4854 } 4855 4856 DbgBreakIf(table_size > RSS_INDIRECTION_TABLE_SIZE); 4857 4858 if(table_size > RSS_INDIRECTION_TABLE_SIZE) 4859 { 4860 table_size = RSS_INDIRECTION_TABLE_SIZE; 4861 } 4862 4863 if(CHIP_NUM(pdev) == CHIP_NUM_5709) 4864 { 4865 REG_RD(pdev, rlup.rlup_rss_config, &val); 4866 val &= ~RLUP_RSS_CONFIG_IPV4_RSS_TYPE_OFF_XI; 4867 val &= ~RLUP_RSS_CONFIG_IPV6_RSS_TYPE_OFF_XI; 4868 REG_WR(pdev, rlup.rlup_rss_config, val); 4869 4870 val = (rss_key[0] << 24) | 4871 (rss_key[1] << 16) | 4872 (rss_key[2] << 8) | 4873 rss_key[3]; 4874 REG_WR(pdev, rlup.rlup_rss_key1, val); 4875 4876 val = (rss_key[4] << 24) | 4877 (rss_key[5] << 16) | 4878 (rss_key[6] << 8) | 4879 rss_key[7]; 4880 REG_WR(pdev, rlup.rlup_rss_key2, val); 4881 4882 val = (rss_key[8] << 24) | 4883 (rss_key[9] << 16) | 4884 (rss_key[10] << 8) | 4885 rss_key[11]; 4886 REG_WR(pdev, rlup.rlup_rss_key3, val); 4887 4888 val = (rss_key[12] << 24) | 4889 (rss_key[13] << 16) | 4890 (rss_key[14] << 8) | 4891 rss_key[15]; 4892 REG_WR(pdev, rlup.rlup_rss_key4, val); 4893 4894 val = (rss_key[16] << 24) | 4895 (rss_key[17] << 16) | 4896 (rss_key[18] << 8) | 4897 rss_key[19]; 4898 REG_WR(pdev, rlup.rlup_ipv6_rss_key5, val); 4899 4900 val = (rss_key[20] << 24) | 4901 (rss_key[21] << 16) | 4902 (rss_key[22] << 8) | 4903 rss_key[23]; 4904 REG_WR(pdev, rlup.rlup_ipv6_rss_key6, val); 4905 4906 val = (rss_key[24] << 24) | 4907 (rss_key[25] << 16) | 4908 (rss_key[26] << 8) | 4909 rss_key[27]; 4910 REG_WR(pdev, rlup.rlup_ipv6_rss_key7, val); 4911 4912 val = (rss_key[28] << 24) | 4913 (rss_key[29] << 16) | 4914 (rss_key[30] << 8) | 4915 rss_key[31]; 4916 REG_WR(pdev, rlup.rlup_ipv6_rss_key8, val); 4917 4918 val = (rss_key[32] << 24) | 4919 (rss_key[33] << 16) | 4920 (rss_key[34] << 8) | 4921 rss_key[35]; 4922 REG_WR(pdev, rlup.rlup_ipv6_rss_key9, val); 4923 4924 val = (rss_key[36] << 24) | 4925 (rss_key[37] << 16) | 4926 (rss_key[38] << 8) | 4927 rss_key[39]; 4928 REG_WR(pdev, rlup.rlup_ipv6_rss_key10, val); 4929 } 4930 4931 rss_table_virt = pdev->rx_info.rss_ind_table_virt; 4932 rss_table_phy = pdev->rx_info.rss_ind_table_phy; 4933 4934 for(idx = 0; idx < table_size; idx++) 4935 { 4936 rss_table_virt[idx] = indirection_table[idx]; 4937 } 4938 4939 prod_qe = pdev->kq_info.kwq_prod_qe; 4940 prod_idx = pdev->kq_info.kwq_prod_idx; 4941 4942 /* Initialize the RSS update KWQE. */ 4943 rss_update = (l2_kwqe_rss_table_update_t *) prod_qe; 4944 4945 rss_update->rss_flags = L2_KWQE_FLAGS_LAYER_MASK_L2; 4946 rss_update->rss_opcode = L2_KWQE_OPCODE_VALUE_UPDATE_RSS; 4947 4948 rss_update->rss_table_size = (u16_t) table_size; 4949 rss_update->rss_table_haddr_lo = rss_table_phy.as_u32.low; 4950 rss_update->rss_table_haddr_hi = rss_table_phy.as_u32.high; 4951 rss_update->rss_host_opaque = 0; 4952 rss_update->rss_hash_type = hash_type; 4953 4954 #if RSS_LOOKUP_TABLE_WA 4955 rss_table_virt += RSS_INDIRECTION_TABLE_SIZE; 4956 LM_INC64(&rss_table_phy, RSS_INDIRECTION_TABLE_SIZE); 4957 4958 rss_update->rss_lookup_table_lo = rss_table_phy.as_u32.low; 4959 rss_update->rss_lookup_table_hi = rss_table_phy.as_u32.high; 4960 4961 rss_gen_tables(rss_key, (u32_t *) rss_table_virt); 4962 #endif 4963 4964 /* Advance to the next KWQE. */ 4965 if(prod_qe == pdev->kq_info.kwq_last_qe) 4966 { 4967 prod_qe = pdev->kq_info.kwq_virt; 4968 } 4969 else 4970 { 4971 prod_qe++; 4972 } 4973 prod_idx++; 4974 4975 /* Initialize the RSS enable KWQE. */ 4976 rss_update = (l2_kwqe_rss_table_update_t *) prod_qe; 4977 4978 rss_update->rss_flags = L2_KWQE_FLAGS_LAYER_MASK_L2; 4979 rss_update->rss_opcode = L2_KWQE_OPCODE_VALUE_ENABLE_RSS; 4980 rss_update->rss_host_opaque = 0; 4981 rss_update->rss_hash_type = hash_type; 4982 4983 /* Advance to the next KWQE. */ 4984 if(prod_qe == pdev->kq_info.kwq_last_qe) 4985 { 4986 prod_qe = pdev->kq_info.kwq_virt; 4987 } 4988 else 4989 { 4990 prod_qe++; 4991 } 4992 prod_idx++; 4993 4994 pdev->kq_info.kwq_prod_qe = prod_qe; 4995 pdev->kq_info.kwq_prod_idx = prod_idx; 4996 4997 MBQ_WR16( 4998 pdev, 4999 GET_CID(pdev->kq_info.kwq_cid_addr), 5000 OFFSETOF(krnlq_context_t, krnlq_host_qidx), 5001 prod_idx); 5002 5003 return LM_STATUS_SUCCESS; 5004 } /* lm_enable_rss */ 5005 #else /* LM_LEAGCY_MODE_SUPPORT */ 5006 /******************************************************************************* 5007 * Description: 5008 * 5009 * Return: 5010 ******************************************************************************/ 5011 lm_status_t 5012 lm_enable_rss( 5013 lm_device_t *pdev, 5014 lm_rss_hash_t hash_type, 5015 PROCESSOR_NUMBER *indirection_table, 5016 u32_t table_size, 5017 u8_t *hash_key, 5018 u32_t key_size, 5019 u8_t *cpu_tbl, 5020 u8_t *rss_qidx_tbl) 5021 { 5022 l2_kwqe_rss_table_update_t *rss_update; 5023 u8_t rss_key[RSS_HASH_KEY_SIZE]; 5024 lm_address_t rss_table_phy; 5025 u8_t *rss_table_virt; 5026 kwqe_t *prod_qe; 5027 u16_t prod_idx; 5028 u32_t idx; 5029 u32_t val; 5030 5031 if(pdev->kq_info.kwqe_left < 2) 5032 { 5033 pdev->kq_info.no_kwq_bd_left++; 5034 return LM_STATUS_RESOURCE; 5035 } 5036 5037 pdev->kq_info.kwqe_left -= 2; 5038 5039 DbgBreakIf(key_size > RSS_HASH_KEY_SIZE); 5040 5041 /* Initialize the rss key array. */ 5042 if(key_size > RSS_HASH_KEY_SIZE) 5043 { 5044 key_size = RSS_HASH_KEY_SIZE; 5045 } 5046 5047 for(idx = 0; idx < key_size; idx++) 5048 { 5049 rss_key[idx] = hash_key[idx]; 5050 } 5051 5052 for(idx = key_size; idx < RSS_HASH_KEY_SIZE; idx++) 5053 { 5054 rss_key[idx] = 0; 5055 } 5056 5057 DbgBreakIf(table_size > RSS_INDIRECTION_TABLE_SIZE); 5058 5059 if(table_size > RSS_INDIRECTION_TABLE_SIZE) 5060 { 5061 table_size = RSS_INDIRECTION_TABLE_SIZE; 5062 } 5063 5064 if(CHIP_NUM(pdev) == CHIP_NUM_5709) 5065 { 5066 REG_RD(pdev, rlup.rlup_rss_config, &val); 5067 val &= ~RLUP_RSS_CONFIG_IPV4_RSS_TYPE_OFF_XI; 5068 val &= ~RLUP_RSS_CONFIG_IPV6_RSS_TYPE_OFF_XI; 5069 REG_WR(pdev, rlup.rlup_rss_config, val); 5070 5071 val = (rss_key[0] << 24) | 5072 (rss_key[1] << 16) | 5073 (rss_key[2] << 8) | 5074 rss_key[3]; 5075 REG_WR(pdev, rlup.rlup_rss_key1, val); 5076 5077 val = (rss_key[4] << 24) | 5078 (rss_key[5] << 16) | 5079 (rss_key[6] << 8) | 5080 rss_key[7]; 5081 REG_WR(pdev, rlup.rlup_rss_key2, val); 5082 5083 val = (rss_key[8] << 24) | 5084 (rss_key[9] << 16) | 5085 (rss_key[10] << 8) | 5086 rss_key[11]; 5087 REG_WR(pdev, rlup.rlup_rss_key3, val); 5088 5089 val = (rss_key[12] << 24) | 5090 (rss_key[13] << 16) | 5091 (rss_key[14] << 8) | 5092 rss_key[15]; 5093 REG_WR(pdev, rlup.rlup_rss_key4, val); 5094 5095 val = (rss_key[16] << 24) | 5096 (rss_key[17] << 16) | 5097 (rss_key[18] << 8) | 5098 rss_key[19]; 5099 REG_WR(pdev, rlup.rlup_ipv6_rss_key5, val); 5100 5101 val = (rss_key[20] << 24) | 5102 (rss_key[21] << 16) | 5103 (rss_key[22] << 8) | 5104 rss_key[23]; 5105 REG_WR(pdev, rlup.rlup_ipv6_rss_key6, val); 5106 5107 val = (rss_key[24] << 24) | 5108 (rss_key[25] << 16) | 5109 (rss_key[26] << 8) | 5110 rss_key[27]; 5111 REG_WR(pdev, rlup.rlup_ipv6_rss_key7, val); 5112 5113 val = (rss_key[28] << 24) | 5114 (rss_key[29] << 16) | 5115 (rss_key[30] << 8) | 5116 rss_key[31]; 5117 REG_WR(pdev, rlup.rlup_ipv6_rss_key8, val); 5118 5119 val = (rss_key[32] << 24) | 5120 (rss_key[33] << 16) | 5121 (rss_key[34] << 8) | 5122 rss_key[35]; 5123 REG_WR(pdev, rlup.rlup_ipv6_rss_key9, val); 5124 5125 val = (rss_key[36] << 24) | 5126 (rss_key[37] << 16) | 5127 (rss_key[38] << 8) | 5128 rss_key[39]; 5129 REG_WR(pdev, rlup.rlup_ipv6_rss_key10, val); 5130 } 5131 5132 rss_table_virt = pdev->rx_info.rss_ind_table_virt; 5133 rss_table_phy = pdev->rx_info.rss_ind_table_phy; 5134 5135 pdev->rx_info.rss_tbl_size = table_size; 5136 if(!cpu_tbl) /* indirection table already had queue idx? */ 5137 { 5138 for(idx = 0; idx < table_size; idx++) 5139 rss_table_virt[idx] = indirection_table[idx].Number; 5140 } 5141 else 5142 { 5143 /* map the cpu num in the indirection table to queue idx 5144 * according to the cpu table passed down from the um, then 5145 * rebuilt the table with queue idx*/ 5146 u8_t *rss_cpu_tbl = &cpu_tbl[1]; 5147 5148 for(idx = 0; idx < table_size; idx++) 5149 { 5150 for(val = 0; val < cpu_tbl[0]; val++) 5151 { 5152 if(indirection_table[idx].Number == rss_cpu_tbl[val]) 5153 { 5154 if(pdev->vars.interrupt_mode == IRQ_MODE_MSIX_BASED || 5155 pdev->vars.interrupt_mode == IRQ_MODE_MSI_BASED) 5156 { 5157 rss_table_virt[idx] = rss_qidx_tbl[rss_cpu_tbl[val] + 1]; 5158 } 5159 else 5160 { 5161 rss_table_virt[idx] = (u8_t)val; 5162 } 5163 break; 5164 } 5165 } 5166 } 5167 } 5168 5169 prod_qe = pdev->kq_info.kwq_prod_qe; 5170 prod_idx = pdev->kq_info.kwq_prod_idx; 5171 5172 /* Initialize the RSS update KWQE. */ 5173 rss_update = (l2_kwqe_rss_table_update_t *) prod_qe; 5174 5175 rss_update->rss_flags = L2_KWQE_FLAGS_LAYER_MASK_L2; 5176 rss_update->rss_opcode = L2_KWQE_OPCODE_VALUE_UPDATE_RSS; 5177 5178 rss_update->rss_table_size = (u16_t) table_size; 5179 rss_update->rss_table_haddr_lo = rss_table_phy.as_u32.low; 5180 rss_update->rss_table_haddr_hi = rss_table_phy.as_u32.high; 5181 rss_update->rss_host_opaque = 0; 5182 rss_update->rss_hash_type = hash_type; 5183 5184 #if RSS_LOOKUP_TABLE_WA 5185 rss_table_virt += RSS_INDIRECTION_TABLE_SIZE; 5186 LM_INC64(&rss_table_phy, RSS_INDIRECTION_TABLE_SIZE); 5187 5188 rss_update->rss_lookup_table_lo = rss_table_phy.as_u32.low; 5189 rss_update->rss_lookup_table_hi = rss_table_phy.as_u32.high; 5190 5191 rss_gen_tables(rss_key, (u32_t *) rss_table_virt); 5192 #endif 5193 5194 /* Advance to the next KWQE. */ 5195 if(prod_qe == pdev->kq_info.kwq_last_qe) 5196 { 5197 prod_qe = pdev->kq_info.kwq_virt; 5198 } 5199 else 5200 { 5201 prod_qe++; 5202 } 5203 prod_idx++; 5204 5205 /* Initialize the RSS enable KWQE. */ 5206 rss_update = (l2_kwqe_rss_table_update_t *) prod_qe; 5207 5208 rss_update->rss_flags = L2_KWQE_FLAGS_LAYER_MASK_L2; 5209 rss_update->rss_opcode = L2_KWQE_OPCODE_VALUE_ENABLE_RSS; 5210 rss_update->rss_host_opaque = 0; 5211 rss_update->rss_hash_type = hash_type; 5212 5213 /* Advance to the next KWQE. */ 5214 if(prod_qe == pdev->kq_info.kwq_last_qe) 5215 { 5216 prod_qe = pdev->kq_info.kwq_virt; 5217 } 5218 else 5219 { 5220 prod_qe++; 5221 } 5222 prod_idx++; 5223 5224 pdev->kq_info.kwq_prod_qe = prod_qe; 5225 pdev->kq_info.kwq_prod_idx = prod_idx; 5226 5227 MBQ_WR16( 5228 pdev, 5229 GET_CID(pdev->kq_info.kwq_cid_addr), 5230 OFFSETOF(krnlq_context_t, krnlq_host_qidx), 5231 prod_idx); 5232 5233 return LM_STATUS_SUCCESS; 5234 } /* lm_enable_rss */ 5235 #endif /* LM_NON_LEGACY_MODE_SUPPORT */ 5236 5237 5238 /******************************************************************************* 5239 * Description: 5240 * 5241 * Return: 5242 ******************************************************************************/ 5243 lm_status_t 5244 lm_disable_rss( 5245 lm_device_t *pdev) 5246 { 5247 l2_kwqe_rss_table_update_t *rss_update; 5248 kwqe_t *prod_qe; 5249 u16_t prod_idx; 5250 u32_t val; 5251 5252 if(pdev->kq_info.kwqe_left < 1) 5253 { 5254 pdev->kq_info.no_kwq_bd_left++; 5255 return LM_STATUS_RESOURCE; 5256 } 5257 5258 pdev->kq_info.kwqe_left -= 1; 5259 5260 if(CHIP_NUM(pdev) == CHIP_NUM_5709) 5261 { 5262 REG_RD(pdev, rlup.rlup_rss_config, &val); 5263 val &= ~RLUP_RSS_CONFIG_IPV4_RSS_TYPE_OFF_XI; 5264 val &= ~RLUP_RSS_CONFIG_IPV6_RSS_TYPE_OFF_XI; 5265 REG_WR(pdev, rlup.rlup_rss_config, val); 5266 } 5267 5268 prod_qe = pdev->kq_info.kwq_prod_qe; 5269 prod_idx = pdev->kq_info.kwq_prod_idx; 5270 5271 /* Initialize the RSS enable KWQE. */ 5272 rss_update = (l2_kwqe_rss_table_update_t *) prod_qe; 5273 5274 rss_update->rss_flags = L2_KWQE_FLAGS_LAYER_MASK_L2; 5275 rss_update->rss_opcode = L2_KWQE_OPCODE_VALUE_DISABLE_RSS; 5276 5277 /* Advance to the next KWQE. */ 5278 if(prod_qe == pdev->kq_info.kwq_last_qe) 5279 { 5280 prod_qe = pdev->kq_info.kwq_virt; 5281 } 5282 else 5283 { 5284 prod_qe++; 5285 } 5286 prod_idx++; 5287 5288 pdev->kq_info.kwq_prod_qe = prod_qe; 5289 pdev->kq_info.kwq_prod_idx = prod_idx; 5290 5291 MBQ_WR16( 5292 pdev, 5293 GET_CID(pdev->kq_info.kwq_cid_addr), 5294 OFFSETOF(krnlq_context_t, krnlq_host_qidx), 5295 prod_idx); 5296 5297 return LM_STATUS_SUCCESS; 5298 } /* lm_disable_rss */ 5299 #endif /* EXCLUDE_RSS_SUPPORT */ 5300 5301 /******************************************************************************* 5302 * Description: 5303 * 5304 * Return: 5305 ******************************************************************************/ 5306 void lm_set_pcie_nfe_report(lm_device_t *pdev) 5307 { 5308 if(CHIP_NUM(pdev) == CHIP_NUM_5709 && 5309 pdev->params.disable_pcie_nfr) 5310 { 5311 u16_t pci_devctl; 5312 REG_RD(pdev,pci_config.pcicfg_device_control,&pci_devctl); 5313 pci_devctl &= ~PCICFG_DEVICE_CONTROL_NON_FATAL_REP_ENA; 5314 REG_WR(pdev,pci_config.pcicfg_device_control,pci_devctl); 5315 } 5316 } 5317 5318 /******************************************************************************* 5319 * Description: 5320 * 5321 * Return: 5322 ******************************************************************************/ 5323 void lm_clear_coalescing_ticks(lm_device_t *pdev) 5324 { 5325 pdev->params.tx_quick_cons_trip = 1; 5326 pdev->params.tx_quick_cons_trip_int = 1; 5327 pdev->params.rx_quick_cons_trip = 1; 5328 pdev->params.rx_quick_cons_trip_int = 1; 5329 pdev->params.comp_prod_trip = 1; 5330 pdev->params.comp_prod_trip_int = 1; 5331 5332 pdev->params.tx_ticks = 0; 5333 pdev->params.tx_ticks_int = 0; 5334 pdev->params.com_ticks = 0; 5335 pdev->params.com_ticks_int = 0; 5336 pdev->params.cmd_ticks = 0; 5337 pdev->params.cmd_ticks_int = 0; 5338 pdev->params.rx_ticks = 0; 5339 pdev->params.rx_ticks_int = 0; 5340 pdev->params.stats_ticks = 0; 5341 5342 /* Xinan per-processor HC configuration. */ 5343 pdev->params.psb_tx_cons_trip = 0x10001; 5344 pdev->params.psb_rx_cons_trip = 0x10001; 5345 pdev->params.psb_comp_prod_trip = 0x10001; 5346 5347 pdev->params.psb_tx_ticks = 0; 5348 pdev->params.psb_rx_ticks = 0; 5349 pdev->params.psb_com_ticks = 0; 5350 pdev->params.psb_cmd_ticks = 0; 5351 pdev->params.psb_period_ticks = 0; 5352 } 5353 5354 u8_t lm_is_mmio_ok(lm_device_t *pdev) 5355 { 5356 u32_t val; 5357 REG_RD(pdev, pci_config.pcicfg_vendor_id, &val); 5358 if (0xffffffff == val) 5359 { 5360 return FALSE; 5361 } 5362 else 5363 { 5364 return TRUE; 5365 } 5366 } 5367 5368 #if defined(LM_NON_LEGACY_MODE_SUPPORT) 5369 /******************************************************************************* 5370 * Description: 5371 * 5372 * Return: 5373 ******************************************************************************/ 5374 void 5375 lm_create_q_group( 5376 lm_device_t *pdev, 5377 u32_t q_group_id, 5378 u32_t lookahead_sz 5379 ) 5380 { 5381 u32_t val; 5382 lm_rx_chain_t *rxq; 5383 5384 rxq = &pdev->rx_info.chain[q_group_id]; 5385 rxq->vmq_lookahead_size = lookahead_sz; 5386 5387 val = lookahead_sz << 16; 5388 CTX_WR( 5389 pdev, 5390 rxq->cid_addr, 5391 WORD_ALIGNED_OFFSETOF(l2_bd_chain_context_t, 5392 l2ctx_vmq_lookahead_sz), 5393 val); 5394 } 5395 5396 /******************************************************************************* 5397 * Description: 5398 * 5399 * Return: 5400 ******************************************************************************/ 5401 lm_status_t 5402 lm_destroy_q_group( 5403 lm_device_t *pdev, 5404 u32_t q_group_id, 5405 u32_t num_queues 5406 ) 5407 { 5408 u32_t num_kwqes_needed; 5409 kwqe_t *prod_qe; 5410 u16_t prod_idx; 5411 l2_kwqe_vm_free_rx_queue_t *kwqe_free_rxq; 5412 5413 num_kwqes_needed = num_queues; 5414 5415 if(pdev->kq_info.kwqe_left < num_kwqes_needed) 5416 { 5417 DbgMessage(pdev, WARN, "No more KWQE left.\n"); 5418 5419 pdev->kq_info.no_kwq_bd_left++; 5420 5421 return LM_STATUS_RESOURCE; 5422 } 5423 5424 prod_qe = pdev->kq_info.kwq_prod_qe; 5425 prod_idx = pdev->kq_info.kwq_prod_idx; 5426 5427 kwqe_free_rxq = (l2_kwqe_vm_free_rx_queue_t *) prod_qe; 5428 5429 if(q_group_id <= RX_CHAIN_IDX3) 5430 { 5431 if(q_group_id == RX_CHAIN_IDX0) 5432 { 5433 u8_t idx; 5434 /* default queue may have more than 1 queue pairs */ 5435 for(idx = 0; idx < num_queues; idx++) 5436 { 5437 kwqe_free_rxq->flags = L2_KWQE_FLAGS_LAYER_MASK_L2; 5438 kwqe_free_rxq->queue_type = L2_NORMAL_QUEUE; 5439 5440 if(idx == 0) 5441 kwqe_free_rxq->qid = (u8_t)q_group_id; 5442 else 5443 { 5444 kwqe_free_rxq->qid = idx + 3; 5445 } 5446 5447 kwqe_free_rxq->opcode = L2_KWQE_OPCODE_VALUE_VM_FREE_RX_QUEUE; 5448 5449 /* Advance to the next KWQE. */ 5450 if(prod_qe == pdev->kq_info.kwq_last_qe) 5451 { 5452 prod_qe = pdev->kq_info.kwq_virt; 5453 } 5454 else 5455 { 5456 prod_qe++; 5457 } 5458 prod_idx++; 5459 5460 pdev->kq_info.kwqe_left -= 1; 5461 kwqe_free_rxq = (l2_kwqe_vm_free_rx_queue_t *) prod_qe; 5462 } 5463 pdev->kq_info.kwq_prod_qe = prod_qe; 5464 pdev->kq_info.kwq_prod_idx = prod_idx; 5465 5466 MBQ_WR16( 5467 pdev, 5468 GET_CID(pdev->kq_info.kwq_cid_addr), 5469 OFFSETOF(krnlq_context_t, krnlq_host_qidx), 5470 prod_idx); 5471 5472 return LM_STATUS_SUCCESS; 5473 } 5474 else 5475 { 5476 kwqe_free_rxq->queue_type = L2_NORMAL_QUEUE; 5477 kwqe_free_rxq->qid = (u8_t)q_group_id; 5478 pdev->kq_info.kwqe_left -= 1; 5479 #if INCLUDE_OFLD_SUPPORT 5480 if(q_group_id == RX_CHAIN_IDX2 && 5481 !s_list_is_empty(&pdev->rx_info.chain[RX_CHAIN_IDX1].active_descq)) 5482 { 5483 kwqe_free_rxq->flags = L2_KWQE_FLAGS_LAYER_MASK_L2; 5484 kwqe_free_rxq->opcode = L2_KWQE_OPCODE_VALUE_VM_FREE_RX_QUEUE; 5485 5486 /* Advance to the next KWQE. */ 5487 if(prod_qe == pdev->kq_info.kwq_last_qe) 5488 { 5489 prod_qe = pdev->kq_info.kwq_virt; 5490 } 5491 else 5492 { 5493 prod_qe++; 5494 } 5495 prod_idx++; 5496 5497 /* flush the catchup RX queue too */ 5498 kwqe_free_rxq = (l2_kwqe_vm_free_rx_queue_t *) prod_qe; 5499 kwqe_free_rxq->queue_type = L2_NORMAL_QUEUE; 5500 kwqe_free_rxq->qid = (u8_t)RX_CHAIN_IDX1; 5501 pdev->kq_info.kwqe_left -= 1; 5502 } 5503 #endif 5504 } 5505 } 5506 else 5507 { 5508 kwqe_free_rxq->queue_type = L2_VM_QUEUE; 5509 kwqe_free_rxq->qid = (u8_t)q_group_id; 5510 pdev->kq_info.kwqe_left -= 1; 5511 } 5512 kwqe_free_rxq->flags = L2_KWQE_FLAGS_LAYER_MASK_L2; 5513 kwqe_free_rxq->opcode = L2_KWQE_OPCODE_VALUE_VM_FREE_RX_QUEUE; 5514 5515 /* Advance to the next KWQE. */ 5516 if(prod_qe == pdev->kq_info.kwq_last_qe) 5517 { 5518 prod_qe = pdev->kq_info.kwq_virt; 5519 } 5520 else 5521 { 5522 prod_qe++; 5523 } 5524 prod_idx++; 5525 5526 pdev->kq_info.kwq_prod_qe = prod_qe; 5527 pdev->kq_info.kwq_prod_idx = prod_idx; 5528 5529 MBQ_WR16( 5530 pdev, 5531 GET_CID(pdev->kq_info.kwq_cid_addr), 5532 OFFSETOF(krnlq_context_t, krnlq_host_qidx), 5533 prod_idx); 5534 5535 return LM_STATUS_SUCCESS; 5536 } 5537 5538 /******************************************************************************* 5539 * Description: 5540 * 5541 * Return: 5542 ******************************************************************************/ 5543 VOID 5544 lm_update_defq_filter_ctx( 5545 lm_device_t *pdev, 5546 u8_t valid 5547 ) 5548 { 5549 u32_t ctx_offset = pdev->vars.hw_filter_ctx_offset; 5550 u32_t val = 0; 5551 5552 if(valid) 5553 val |= L2_VM_FILTER_MAC << 16; 5554 5555 REG_WR_IND( 5556 pdev, 5557 OFFSETOF(reg_space_t, rxp.rxp_scratch[0])+ctx_offset, 5558 val); 5559 } 5560 5561 /******************************************************************************* 5562 * Description: 5563 * 5564 * Return: 5565 ******************************************************************************/ 5566 lm_status_t 5567 lm_chng_q_group_filter( 5568 lm_device_t *pdev, 5569 u32_t q_group_id, 5570 u8_t *dest_mac, 5571 u16_t *vlan_ptr, 5572 u32_t filter_id 5573 ) 5574 { 5575 kwqe_t *prod_qe; 5576 u16_t prod_idx; 5577 5578 if(pdev->kq_info.kwqe_left < 1) 5579 { 5580 DbgMessage(pdev, WARN, "No more KWQE left.\n"); 5581 5582 pdev->kq_info.no_kwq_bd_left++; 5583 5584 return LM_STATUS_RESOURCE; 5585 } 5586 5587 prod_qe = pdev->kq_info.kwq_prod_qe; 5588 prod_idx = pdev->kq_info.kwq_prod_idx; 5589 5590 pdev->kq_info.kwqe_left -= 1; 5591 if(dest_mac == NULL && vlan_ptr == NULL) 5592 { 5593 /* clear filter operation */ 5594 l2_kwqe_vm_remove_rx_filter_t * kwqe_remove_rx_filter = 5595 (l2_kwqe_vm_remove_rx_filter_t *) prod_qe; 5596 kwqe_remove_rx_filter->flags = L2_KWQE_FLAGS_LAYER_MASK_L2; 5597 kwqe_remove_rx_filter->qid = (u8_t)q_group_id; 5598 kwqe_remove_rx_filter->filter_id = (u8_t)filter_id; 5599 kwqe_remove_rx_filter->opcode = L2_KWQE_OPCODE_VALUE_VM_REMOVE_RX_FILTER; 5600 } 5601 else 5602 { 5603 /* set filter operation */ 5604 l2_kwqe_vm_set_rx_filter_t * kwqe_set_rx_filter = 5605 (l2_kwqe_vm_set_rx_filter_t *) prod_qe; 5606 5607 kwqe_set_rx_filter->flags = L2_KWQE_FLAGS_LAYER_MASK_L2; 5608 kwqe_set_rx_filter->qid = (u8_t)q_group_id; 5609 kwqe_set_rx_filter->filter_id = (u8_t)filter_id; 5610 if(vlan_ptr) 5611 { 5612 kwqe_set_rx_filter->vlan = *vlan_ptr; 5613 kwqe_set_rx_filter->filter_type = L2_VM_FILTER_MAC_VLAN; 5614 } 5615 else 5616 { 5617 kwqe_set_rx_filter->filter_type = L2_VM_FILTER_MAC; 5618 } 5619 kwqe_set_rx_filter->opcode = L2_KWQE_OPCODE_VALUE_VM_SET_RX_FILTER; 5620 } 5621 5622 /* Advance to the next KWQE. */ 5623 if(prod_qe == pdev->kq_info.kwq_last_qe) 5624 { 5625 prod_qe = pdev->kq_info.kwq_virt; 5626 } 5627 else 5628 { 5629 prod_qe++; 5630 } 5631 prod_idx++; 5632 5633 pdev->kq_info.kwq_prod_qe = prod_qe; 5634 pdev->kq_info.kwq_prod_idx = prod_idx; 5635 5636 MBQ_WR16( 5637 pdev, 5638 GET_CID(pdev->kq_info.kwq_cid_addr), 5639 OFFSETOF(krnlq_context_t, krnlq_host_qidx), 5640 prod_idx); 5641 return LM_STATUS_PENDING; 5642 } 5643 5644 /******************************************************************************* 5645 * Description: 5646 * 5647 * Return: 5648 ******************************************************************************/ 5649 u32_t 5650 lm_service_l2_kcqes( 5651 struct _lm_device_t *pdev, 5652 kcqe_t *cqe_ptr[], 5653 u32_t num_cqes) 5654 { 5655 u32_t cqe_serviced_cnt; 5656 u32_t cqe_cnt; 5657 u8_t success; 5658 kcqe_t *kcqe; 5659 lm_status_t lm_status; 5660 5661 cqe_serviced_cnt = 0; 5662 while(num_cqes) 5663 { 5664 /* Determine the number of cqes for a completion. Some 5665 * completions span several cqes. */ 5666 cqe_cnt = 0; 5667 while(cqe_ptr[cqe_cnt]->kcqe_flags & KCQE_FLAGS_NEXT) 5668 { 5669 cqe_cnt++; 5670 } 5671 cqe_cnt++; 5672 5673 DbgBreakIf(cqe_cnt > num_cqes); 5674 5675 kcqe = *cqe_ptr; 5676 5677 DbgBreakIf((kcqe->kcqe_flags & KCQE_FLAGS_LAYER_MASK) != 5678 KCQE_FLAGS_LAYER_MASK_L2); 5679 5680 switch(kcqe->kcqe_opcode) 5681 { 5682 case L2_KCQE_OPCODE_VALUE_VM_FREE_RX_QUEUE: 5683 /* initiate rx buffer abort */ 5684 { 5685 l2_kcqe_vm_free_rx_queue_t *kcqe_free_rxq; 5686 5687 kcqe_free_rxq = (l2_kcqe_vm_free_rx_queue_t *)kcqe; 5688 mm_q_grp_abort_rx_request( 5689 pdev, 5690 kcqe_free_rxq->qid); 5691 } 5692 break; 5693 5694 case L2_KCQE_OPCODE_VALUE_VM_SET_RX_FILTER: 5695 case L2_KCQE_OPCODE_VALUE_VM_REMOVE_RX_FILTER: 5696 { 5697 l2_kcqe_vm_set_rx_filter_t *kcqe_filter; 5698 5699 kcqe_filter = (l2_kcqe_vm_set_rx_filter_t *)kcqe; 5700 if(kcqe_filter->status == SC_SUCCESS) 5701 { 5702 lm_status = LM_STATUS_SUCCESS; 5703 } 5704 else 5705 { 5706 lm_status = LM_STATUS_FAILURE; 5707 } 5708 mm_comp_l2_filter_chng_req( 5709 pdev, 5710 lm_status, 5711 kcqe_filter->qid); 5712 } 5713 break; 5714 5715 case L2_KCQE_OPCODE_VALUE_VM_ALLOC_RX_QUEUE: 5716 case L2_KCQE_OPCODE_VALUE_RX_PACKET: 5717 case L2_KCQE_OPCODE_VALUE_ENABLE_RSS: 5718 case L2_KCQE_OPCODE_VALUE_DISABLE_RSS: 5719 case L2_KCQE_OPCODE_VALUE_UPDATE_RSS: 5720 case L2_KCQE_OPCODE_VALUE_FLUSH_BD_CHAIN: 5721 /* no need to do anything in the driver */ 5722 break; 5723 5724 default: 5725 DbgBreakMsg("invalid l2 kcqe.\n"); 5726 break; 5727 } 5728 5729 cqe_ptr += cqe_cnt; 5730 num_cqes -= cqe_cnt; 5731 cqe_serviced_cnt += cqe_cnt; 5732 } 5733 5734 return cqe_serviced_cnt; 5735 } 5736 #endif /* LM_NON_LEGACY_MODE_SUPPORT */ 5737