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