1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 NetXen, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 #include <sys/types.h> 26 #include <sys/conf.h> 27 #include <sys/debug.h> 28 #include <sys/stropts.h> 29 #include <sys/stream.h> 30 #include <sys/strlog.h> 31 #include <sys/kmem.h> 32 #include <sys/stat.h> 33 #include <sys/kstat.h> 34 #include <sys/vtrace.h> 35 #include <sys/dlpi.h> 36 #include <sys/strsun.h> 37 #include <sys/ethernet.h> 38 #include <sys/modctl.h> 39 #include <sys/errno.h> 40 #include <sys/dditypes.h> 41 #include <sys/ddi.h> 42 #include <sys/sunddi.h> 43 #include <sys/sysmacros.h> 44 #include <sys/pci.h> 45 46 #include "unm_nic_hw.h" 47 #include "unm_nic.h" 48 #include "nic_phan_reg.h" 49 #include "nic_cmn.h" 50 51 typedef unsigned int nx_rcode_t; 52 53 #include "nx_errorcode.h" 54 #include "nxhal_nic_interface.h" 55 56 #define NXHAL_VERSION 1 57 58 #define NX_OS_CRB_RETRY_COUNT 4000 59 60 #define NX_CDRP_CLEAR 0x00000000 61 #define NX_CDRP_CMD_BIT 0x80000000 62 63 /* 64 * All responses must have the NX_CDRP_CMD_BIT cleared 65 * in the crb NX_CDRP_CRB_OFFSET. 66 */ 67 #define NX_CDRP_FORM_RSP(rsp) (rsp) 68 #define NX_CDRP_IS_RSP(rsp) (((rsp) & NX_CDRP_CMD_BIT) == 0) 69 70 #define NX_CDRP_RSP_OK 0x00000001 71 #define NX_CDRP_RSP_FAIL 0x00000002 72 #define NX_CDRP_RSP_TIMEOUT 0x00000003 73 74 /* 75 * All commands must have the NX_CDRP_CMD_BIT set in 76 * the crb NX_CDRP_CRB_OFFSET. 77 */ 78 #define NX_CDRP_FORM_CMD(cmd) (NX_CDRP_CMD_BIT | (cmd)) 79 #define NX_CDRP_IS_CMD(cmd) (((cmd) & NX_CDRP_CMD_BIT) != 0) 80 81 #define NX_CDRP_CMD_SUBMIT_CAPABILITIES 0x00000001 82 #define NX_CDRP_CMD_READ_MAX_RDS_PER_CTX 0x00000002 83 #define NX_CDRP_CMD_READ_MAX_SDS_PER_CTX 0x00000003 84 #define NX_CDRP_CMD_READ_MAX_RULES_PER_CTX 0x00000004 85 #define NX_CDRP_CMD_READ_MAX_RX_CTX 0x00000005 86 #define NX_CDRP_CMD_READ_MAX_TX_CTX 0x00000006 87 #define NX_CDRP_CMD_CREATE_RX_CTX 0x00000007 88 #define NX_CDRP_CMD_DESTROY_RX_CTX 0x00000008 89 #define NX_CDRP_CMD_CREATE_TX_CTX 0x00000009 90 #define NX_CDRP_CMD_DESTROY_TX_CTX 0x0000000a 91 #define NX_CDRP_CMD_SETUP_STATISTICS 0x0000000e 92 #define NX_CDRP_CMD_GET_STATISTICS 0x0000000f 93 #define NX_CDRP_CMD_DELETE_STATISTICS 0x00000010 94 #define NX_CDRP_CMD_SET_MTU 0x00000012 95 #define NX_CDRP_CMD_MAX 0x00000013 96 97 #define NX_DESTROY_CTX_RESET 0 98 #define NX_DESTROY_CTX_D3_RESET 1 99 #define NX_DESTROY_CTX_MAX 2 100 101 /* 102 * Context state 103 */ 104 #define NX_HOST_CTX_STATE_FREED 0 105 #define NX_HOST_CTX_STATE_ALLOCATED 1 106 #define NX_HOST_CTX_STATE_ACTIVE 2 107 #define NX_HOST_CTX_STATE_DISABLED 3 108 #define NX_HOST_CTX_STATE_QUIESCED 4 109 #define NX_HOST_CTX_STATE_MAX 5 110 111 static int 112 netxen_api_lock(struct unm_adapter_s *adapter) 113 { 114 u32 done = 0, timeout = 0; 115 116 for (;;) { 117 /* Acquire PCIE HW semaphore5 */ 118 unm_nic_read_w0(adapter, 119 UNM_PCIE_REG(PCIE_SEM5_LOCK), &done); 120 121 if (done == 1) 122 break; 123 124 if (++timeout >= NX_OS_CRB_RETRY_COUNT) { 125 cmn_err(CE_WARN, "%s: lock timeout.\n", __func__); 126 return (-1); 127 } 128 129 drv_usecwait(1000); 130 } 131 132 #if 0 133 unm_nic_reg_write(adapter, NETXEN_API_LOCK_ID, NX_OS_API_LOCK_DRIVER); 134 #endif 135 return (0); 136 } 137 138 static void 139 netxen_api_unlock(struct unm_adapter_s *adapter) 140 { 141 u32 val; 142 143 /* Release PCIE HW semaphore5 */ 144 unm_nic_read_w0(adapter, 145 UNM_PCIE_REG(PCIE_SEM5_UNLOCK), &val); 146 } 147 148 static u32 149 netxen_poll_rsp(struct unm_adapter_s *adapter) 150 { 151 u32 raw_rsp, rsp = NX_CDRP_RSP_OK; 152 int timeout = 0; 153 154 do { 155 /* give atleast 1ms for firmware to respond */ 156 drv_usecwait(1000); 157 158 if (++timeout > NX_OS_CRB_RETRY_COUNT) 159 return (NX_CDRP_RSP_TIMEOUT); 160 161 adapter->unm_nic_hw_read_wx(adapter, NX_CDRP_CRB_OFFSET, 162 &raw_rsp, 4); 163 164 rsp = LE_TO_HOST_32(raw_rsp); 165 } while (!NX_CDRP_IS_RSP(rsp)); 166 167 return (rsp); 168 } 169 170 static u32 171 netxen_issue_cmd(struct unm_adapter_s *adapter, 172 u32 pci_fn, u32 version, u32 arg1, u32 arg2, u32 arg3, u32 cmd) 173 { 174 u32 rsp; 175 u32 signature = 0; 176 u32 rcode = NX_RCODE_SUCCESS; 177 178 signature = NX_CDRP_SIGNATURE_MAKE(pci_fn, version); 179 180 /* Acquire semaphore before accessing CRB */ 181 if (netxen_api_lock(adapter)) 182 return (NX_RCODE_TIMEOUT); 183 184 unm_nic_reg_write(adapter, NX_SIGN_CRB_OFFSET, 185 HOST_TO_LE_32(signature)); 186 187 unm_nic_reg_write(adapter, NX_ARG1_CRB_OFFSET, 188 HOST_TO_LE_32(arg1)); 189 190 unm_nic_reg_write(adapter, NX_ARG2_CRB_OFFSET, 191 HOST_TO_LE_32(arg2)); 192 193 unm_nic_reg_write(adapter, NX_ARG3_CRB_OFFSET, 194 HOST_TO_LE_32(arg3)); 195 196 unm_nic_reg_write(adapter, NX_CDRP_CRB_OFFSET, 197 HOST_TO_LE_32(NX_CDRP_FORM_CMD(cmd))); 198 199 rsp = netxen_poll_rsp(adapter); 200 201 if (rsp == NX_CDRP_RSP_TIMEOUT) { 202 cmn_err(CE_WARN, "%s: card response timeout.\n", 203 unm_nic_driver_name); 204 205 rcode = NX_RCODE_TIMEOUT; 206 } else if (rsp == NX_CDRP_RSP_FAIL) { 207 adapter->unm_nic_hw_read_wx(adapter, NX_ARG1_CRB_OFFSET, 208 &rcode, 4); 209 rcode = LE_TO_HOST_32(rcode); 210 211 cmn_err(CE_WARN, "%s: failed card response code:0x%x\n", 212 unm_nic_driver_name, rcode); 213 } 214 215 /* Release semaphore */ 216 netxen_api_unlock(adapter); 217 218 return (rcode); 219 } 220 221 int 222 nx_fw_cmd_set_mtu(struct unm_adapter_s *adapter, int mtu) 223 { 224 u32 rcode = NX_RCODE_SUCCESS; 225 struct unm_recv_context_s *recv_ctx = &adapter->recv_ctx[0]; 226 227 if (recv_ctx->state == NX_HOST_CTX_STATE_ACTIVE) 228 rcode = netxen_issue_cmd(adapter, 229 adapter->ahw.pci_func, 230 NXHAL_VERSION, 231 recv_ctx->context_id, 232 mtu, 233 0, 234 NX_CDRP_CMD_SET_MTU); 235 236 if (rcode != NX_RCODE_SUCCESS) 237 return (-EIO); 238 239 return (0); 240 } 241 242 static int 243 nx_fw_cmd_create_rx_ctx(struct unm_adapter_s *adapter) 244 { 245 unm_recv_context_t *recv_ctx = &adapter->recv_ctx[0]; 246 nx_hostrq_rx_ctx_t *prq; 247 nx_cardrsp_rx_ctx_t *prsp; 248 nx_hostrq_rds_ring_t *prq_rds; 249 nx_hostrq_sds_ring_t *prq_sds; 250 nx_cardrsp_rds_ring_t *prsp_rds; 251 nx_cardrsp_sds_ring_t *prsp_sds; 252 unm_rcv_desc_ctx_t *rcv_desc; 253 ddi_dma_cookie_t cookie; 254 ddi_dma_handle_t rqdhdl, rsdhdl; 255 ddi_acc_handle_t rqahdl, rsahdl; 256 uint64_t hostrq_phys_addr, cardrsp_phys_addr; 257 u64 phys_addr; 258 u32 cap, reg; 259 size_t rq_size, rsp_size; 260 void *addr; 261 int i, nrds_rings, nsds_rings, err; 262 263 /* only one sds ring for now */ 264 nrds_rings = adapter->max_rds_rings; 265 nsds_rings = 1; 266 267 rq_size = 268 SIZEOF_HOSTRQ_RX(nx_hostrq_rx_ctx_t, nrds_rings, nsds_rings); 269 rsp_size = 270 SIZEOF_CARDRSP_RX(nx_cardrsp_rx_ctx_t, nrds_rings, nsds_rings); 271 272 if (unm_pci_alloc_consistent(adapter, rq_size, (caddr_t *)&addr, 273 &cookie, &rqdhdl, &rqahdl) != DDI_SUCCESS) 274 return (-ENOMEM); 275 hostrq_phys_addr = cookie.dmac_laddress; 276 prq = (nx_hostrq_rx_ctx_t *)addr; 277 278 if (unm_pci_alloc_consistent(adapter, rsp_size, (caddr_t *)&addr, 279 &cookie, &rsdhdl, &rsahdl) != DDI_SUCCESS) { 280 err = -ENOMEM; 281 goto out_free_rq; 282 } 283 cardrsp_phys_addr = cookie.dmac_laddress; 284 prsp = (nx_cardrsp_rx_ctx_t *)addr; 285 286 prq->host_rsp_dma_addr = HOST_TO_LE_64(cardrsp_phys_addr); 287 288 cap = (NX_CAP0_LEGACY_CONTEXT | NX_CAP0_LEGACY_MN); 289 cap |= (NX_CAP0_JUMBO_CONTIGUOUS); 290 291 prq->capabilities[0] = HOST_TO_LE_32(cap); 292 prq->host_int_crb_mode = 293 HOST_TO_LE_32(NX_HOST_INT_CRB_MODE_SHARED); 294 prq->host_rds_crb_mode = 295 HOST_TO_LE_32(NX_HOST_RDS_CRB_MODE_UNIQUE); 296 297 prq->num_rds_rings = HOST_TO_LE_16(nrds_rings); 298 prq->num_sds_rings = HOST_TO_LE_16(nsds_rings); 299 prq->rds_ring_offset = 0; 300 prq->sds_ring_offset = prq->rds_ring_offset + 301 (sizeof (nx_hostrq_rds_ring_t) * nrds_rings); 302 303 prq_rds = (nx_hostrq_rds_ring_t *)(uintptr_t)(prq->data + 304 prq->rds_ring_offset); 305 306 for (i = 0; i < nrds_rings; i++) { 307 rcv_desc = &recv_ctx->rcv_desc[i]; 308 309 prq_rds[i].host_phys_addr = HOST_TO_LE_64(rcv_desc->phys_addr); 310 prq_rds[i].ring_size = HOST_TO_LE_32(rcv_desc->MaxRxDescCount); 311 prq_rds[i].ring_kind = HOST_TO_LE_32(i); 312 prq_rds[i].buff_size = HOST_TO_LE_64(rcv_desc->dma_size); 313 } 314 315 prq_sds = (nx_hostrq_sds_ring_t *)(uintptr_t)(prq->data + 316 prq->sds_ring_offset); 317 318 prq_sds[0].host_phys_addr = 319 HOST_TO_LE_64(recv_ctx->rcvStatusDesc_physAddr); 320 prq_sds[0].ring_size = HOST_TO_LE_32(adapter->MaxRxDescCount); 321 /* only one msix vector for now */ 322 prq_sds[0].msi_index = HOST_TO_LE_32(0); 323 324 /* now byteswap offsets */ 325 prq->rds_ring_offset = HOST_TO_LE_32(prq->rds_ring_offset); 326 prq->sds_ring_offset = HOST_TO_LE_32(prq->sds_ring_offset); 327 328 phys_addr = hostrq_phys_addr; 329 err = netxen_issue_cmd(adapter, 330 adapter->ahw.pci_func, 331 NXHAL_VERSION, 332 (u32)(phys_addr >> 32), 333 (u32)(phys_addr & 0xffffffff), 334 rq_size, 335 NX_CDRP_CMD_CREATE_RX_CTX); 336 if (err) { 337 cmn_err(CE_WARN, "Failed to create rx ctx in firmware%d\n", 338 err); 339 goto out_free_rsp; 340 } 341 342 343 prsp_rds = ((nx_cardrsp_rds_ring_t *)(uintptr_t) 344 &prsp->data[prsp->rds_ring_offset]); 345 346 for (i = 0; i < LE_TO_HOST_32(prsp->num_rds_rings); i++) { 347 rcv_desc = &recv_ctx->rcv_desc[i]; 348 349 reg = LE_TO_HOST_32(prsp_rds[i].host_producer_crb); 350 rcv_desc->host_rx_producer = UNM_NIC_REG(reg - 0x200); 351 } 352 353 prsp_sds = ((nx_cardrsp_sds_ring_t *)(uintptr_t) 354 &prsp->data[prsp->sds_ring_offset]); 355 reg = LE_TO_HOST_32(prsp_sds[0].host_consumer_crb); 356 recv_ctx->host_sds_consumer = UNM_NIC_REG(reg - 0x200); 357 358 reg = LE_TO_HOST_32(prsp_sds[0].interrupt_crb); 359 adapter->interrupt_crb = UNM_NIC_REG(reg - 0x200); 360 361 recv_ctx->state = LE_TO_HOST_32(prsp->host_ctx_state); 362 recv_ctx->context_id = LE_TO_HOST_16(prsp->context_id); 363 recv_ctx->virt_port = LE_TO_HOST_16(prsp->virt_port); 364 365 out_free_rsp: 366 unm_pci_free_consistent(&rsdhdl, &rsahdl); 367 out_free_rq: 368 unm_pci_free_consistent(&rqdhdl, &rqahdl); 369 return (err); 370 } 371 372 static void 373 nx_fw_cmd_destroy_rx_ctx(struct unm_adapter_s *adapter) 374 { 375 struct unm_recv_context_s *recv_ctx = &adapter->recv_ctx[0]; 376 377 if (netxen_issue_cmd(adapter, 378 adapter->ahw.pci_func, 379 NXHAL_VERSION, 380 recv_ctx->context_id, 381 NX_DESTROY_CTX_RESET, 382 0, 383 NX_CDRP_CMD_DESTROY_RX_CTX)) { 384 385 cmn_err(CE_WARN, "%s: Failed to destroy rx ctx in firmware\n", 386 unm_nic_driver_name); 387 } 388 } 389 390 static int 391 nx_fw_cmd_create_tx_ctx(struct unm_adapter_s *adapter) 392 { 393 nx_hostrq_tx_ctx_t *prq; 394 nx_hostrq_cds_ring_t *prq_cds; 395 nx_cardrsp_tx_ctx_t *prsp; 396 ddi_dma_cookie_t cookie; 397 ddi_dma_handle_t rqdhdl, rsdhdl; 398 ddi_acc_handle_t rqahdl, rsahdl; 399 void *rq_addr, *rsp_addr; 400 size_t rq_size, rsp_size; 401 u32 temp; 402 int err = 0; 403 u64 offset, phys_addr; 404 uint64_t rq_phys_addr, rsp_phys_addr; 405 406 rq_size = SIZEOF_HOSTRQ_TX(nx_hostrq_tx_ctx_t); 407 if (unm_pci_alloc_consistent(adapter, rq_size, (caddr_t *)&rq_addr, 408 &cookie, &rqdhdl, &rqahdl) != DDI_SUCCESS) 409 return (-ENOMEM); 410 rq_phys_addr = cookie.dmac_laddress; 411 412 rsp_size = SIZEOF_CARDRSP_TX(nx_cardrsp_tx_ctx_t); 413 if (unm_pci_alloc_consistent(adapter, rsp_size, (caddr_t *)&rsp_addr, 414 &cookie, &rsdhdl, &rsahdl) != DDI_SUCCESS) { 415 err = -ENOMEM; 416 goto out_free_rq; 417 } 418 rsp_phys_addr = cookie.dmac_laddress; 419 420 (void) memset(rq_addr, 0, rq_size); 421 prq = (nx_hostrq_tx_ctx_t *)rq_addr; 422 423 (void) memset(rsp_addr, 0, rsp_size); 424 prsp = (nx_cardrsp_tx_ctx_t *)rsp_addr; 425 426 prq->host_rsp_dma_addr = HOST_TO_LE_64(rsp_phys_addr); 427 428 temp = (NX_CAP0_LEGACY_CONTEXT | NX_CAP0_LEGACY_MN); 429 prq->capabilities[0] = HOST_TO_LE_32(temp); 430 431 prq->host_int_crb_mode = 432 HOST_TO_LE_32(NX_HOST_INT_CRB_MODE_SHARED); 433 434 prq->interrupt_ctl = 0; 435 prq->msi_index = 0; 436 437 prq->dummy_dma_addr = HOST_TO_LE_64(adapter->dummy_dma.phys_addr); 438 439 offset = adapter->ctxDesc_physAddr + sizeof (RingContext); 440 prq->cmd_cons_dma_addr = HOST_TO_LE_64(offset); 441 442 prq_cds = &prq->cds_ring; 443 444 prq_cds->host_phys_addr = 445 HOST_TO_LE_64(adapter->ahw.cmdDesc_physAddr); 446 447 prq_cds->ring_size = HOST_TO_LE_32(adapter->MaxTxDescCount); 448 449 phys_addr = rq_phys_addr; 450 err = netxen_issue_cmd(adapter, 451 adapter->ahw.pci_func, 452 NXHAL_VERSION, 453 (u32)(phys_addr >> 32), 454 ((u32)phys_addr & 0xffffffff), 455 rq_size, 456 NX_CDRP_CMD_CREATE_TX_CTX); 457 458 if (err == NX_RCODE_SUCCESS) { 459 temp = LE_TO_HOST_32(prsp->cds_ring.host_producer_crb); 460 adapter->crb_addr_cmd_producer = 461 UNM_NIC_REG(temp - 0x200); 462 #if 0 463 adapter->tx_state = 464 LE_TO_HOST_32(prsp->host_ctx_state); 465 #endif 466 adapter->tx_context_id = 467 LE_TO_HOST_16(prsp->context_id); 468 } else { 469 cmn_err(CE_WARN, "Failed to create tx ctx in firmware%d\n", 470 err); 471 err = -EIO; 472 } 473 474 unm_pci_free_consistent(&rsdhdl, &rsahdl); 475 476 out_free_rq: 477 unm_pci_free_consistent(&rqdhdl, &rqahdl); 478 479 return (err); 480 } 481 482 static void 483 nx_fw_cmd_destroy_tx_ctx(struct unm_adapter_s *adapter) 484 { 485 if (netxen_issue_cmd(adapter, 486 adapter->ahw.pci_func, 487 NXHAL_VERSION, 488 adapter->tx_context_id, 489 NX_DESTROY_CTX_RESET, 490 0, 491 NX_CDRP_CMD_DESTROY_TX_CTX)) { 492 493 cmn_err(CE_WARN, "%s: Failed to destroy tx ctx in firmware\n", 494 unm_nic_driver_name); 495 } 496 } 497 498 static u64 ctx_addr_sig_regs[][3] = { 499 {UNM_NIC_REG(0x188), UNM_NIC_REG(0x18c), UNM_NIC_REG(0x1c0)}, 500 {UNM_NIC_REG(0x190), UNM_NIC_REG(0x194), UNM_NIC_REG(0x1c4)}, 501 {UNM_NIC_REG(0x198), UNM_NIC_REG(0x19c), UNM_NIC_REG(0x1c8)}, 502 {UNM_NIC_REG(0x1a0), UNM_NIC_REG(0x1a4), UNM_NIC_REG(0x1cc)} 503 }; 504 505 #define CRB_CTX_ADDR_REG_LO(FUNC_ID) (ctx_addr_sig_regs[FUNC_ID][0]) 506 #define CRB_CTX_ADDR_REG_HI(FUNC_ID) (ctx_addr_sig_regs[FUNC_ID][2]) 507 #define CRB_CTX_SIGNATURE_REG(FUNC_ID) (ctx_addr_sig_regs[FUNC_ID][1]) 508 509 struct netxen_recv_crb { 510 u32 crb_rcv_producer[NUM_RCV_DESC_RINGS]; 511 u32 crb_sts_consumer; 512 }; 513 514 static struct netxen_recv_crb recv_crb_registers[] = { 515 /* Instance 0 */ 516 { 517 /* crb_rcv_producer: */ 518 { 519 UNM_NIC_REG(0x100), 520 /* Jumbo frames */ 521 UNM_NIC_REG(0x110), 522 /* LRO */ 523 UNM_NIC_REG(0x120) 524 }, 525 /* crb_sts_consumer: */ 526 UNM_NIC_REG(0x138), 527 }, 528 /* Instance 1 */ 529 { 530 /* crb_rcv_producer: */ 531 { 532 UNM_NIC_REG(0x144), 533 /* Jumbo frames */ 534 UNM_NIC_REG(0x154), 535 /* LRO */ 536 UNM_NIC_REG(0x164) 537 }, 538 /* crb_sts_consumer: */ 539 UNM_NIC_REG(0x17c), 540 }, 541 /* Instance 2 */ 542 { 543 /* crb_rcv_producer: */ 544 { 545 UNM_NIC_REG(0x1d8), 546 /* Jumbo frames */ 547 UNM_NIC_REG(0x1f8), 548 /* LRO */ 549 UNM_NIC_REG(0x208) 550 }, 551 /* crb_sts_consumer: */ 552 UNM_NIC_REG(0x220), 553 }, 554 /* Instance 3 */ 555 { 556 /* crb_rcv_producer: */ 557 { 558 UNM_NIC_REG(0x22c), 559 /* Jumbo frames */ 560 UNM_NIC_REG(0x23c), 561 /* LRO */ 562 UNM_NIC_REG(0x24c) 563 }, 564 /* crb_sts_consumer: */ 565 UNM_NIC_REG(0x264), 566 }, 567 }; 568 569 static uint32_t sw_int_mask[4] = { 570 CRB_SW_INT_MASK_0, CRB_SW_INT_MASK_1, 571 CRB_SW_INT_MASK_2, CRB_SW_INT_MASK_3 572 }; 573 574 static int 575 netxen_init_old_ctx(struct unm_adapter_s *adapter) 576 { 577 hardware_context *hw = &adapter->ahw; 578 struct unm_recv_context_s *recv_ctx; 579 unm_rcv_desc_ctx_t *rcv_desc; 580 int ctx, ring, func_id = adapter->portnum; 581 unsigned int temp; 582 583 adapter->ctxDesc->CmdRingAddrLo = hw->cmdDesc_physAddr & 0xffffffffUL; 584 adapter->ctxDesc->CmdRingAddrHi = ((U64)hw->cmdDesc_physAddr >> 32); 585 adapter->ctxDesc->CmdRingSize = adapter->MaxTxDescCount; 586 587 for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { 588 recv_ctx = &adapter->recv_ctx[ctx]; 589 590 for (ring = 0; ring < adapter->max_rds_rings; ring++) { 591 rcv_desc = &recv_ctx->rcv_desc[ring]; 592 593 adapter->ctxDesc->RcvContext[ring].RcvRingAddrLo = 594 rcv_desc->phys_addr & 0xffffffffUL; 595 adapter->ctxDesc->RcvContext[ring].RcvRingAddrHi = 596 ((U64)rcv_desc->phys_addr>>32); 597 adapter->ctxDesc->RcvContext[ring].RcvRingSize = 598 rcv_desc->MaxRxDescCount; 599 600 rcv_desc->host_rx_producer = 601 recv_crb_registers[adapter->portnum]. 602 crb_rcv_producer[ring]; 603 } 604 605 adapter->ctxDesc->StsRingAddrLo = 606 recv_ctx->rcvStatusDesc_physAddr & 0xffffffff; 607 adapter->ctxDesc->StsRingAddrHi = 608 recv_ctx->rcvStatusDesc_physAddr >> 32; 609 adapter->ctxDesc->StsRingSize = adapter->MaxRxDescCount; 610 611 recv_ctx->host_sds_consumer = 612 recv_crb_registers[adapter->portnum].crb_sts_consumer; 613 } 614 615 adapter->interrupt_crb = sw_int_mask[adapter->portnum]; 616 617 temp = lower32(adapter->ctxDesc_physAddr); 618 adapter->unm_nic_hw_write_wx(adapter, CRB_CTX_ADDR_REG_LO(func_id), 619 &temp, 4); 620 temp = upper32(adapter->ctxDesc_physAddr); 621 adapter->unm_nic_hw_write_wx(adapter, CRB_CTX_ADDR_REG_HI(func_id), 622 &temp, 4); 623 temp = UNM_CTX_SIGNATURE | func_id; 624 adapter->unm_nic_hw_write_wx(adapter, CRB_CTX_SIGNATURE_REG(func_id), 625 &temp, 4); 626 627 return (0); 628 } 629 630 void 631 netxen_destroy_rxtx(struct unm_adapter_s *adapter) 632 { 633 if (adapter->fw_major >= 4) { 634 nx_fw_cmd_destroy_tx_ctx(adapter); 635 nx_fw_cmd_destroy_rx_ctx(adapter); 636 } 637 } 638 639 int 640 netxen_create_rxtx(struct unm_adapter_s *adapter) 641 { 642 int err; 643 644 if (adapter->fw_major >= 4) { 645 err = nx_fw_cmd_create_rx_ctx(adapter); 646 if (err) 647 return (err); 648 err = nx_fw_cmd_create_tx_ctx(adapter); 649 if (err) 650 nx_fw_cmd_destroy_rx_ctx(adapter); 651 return (err); 652 } else { 653 return (netxen_init_old_ctx(adapter)); 654 } 655 } 656