1/* 2 * Copyright (C) 2003 - 2009 NetXen, Inc. 3 * Copyright (C) 2009 - QLogic Corporation. 4 * All rights reserved. 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 2 9 * of the License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, but 12 * WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 19 * MA 02111-1307, USA. 20 * 21 * The full GNU General Public License is included in this distribution 22 * in the file called "COPYING". 23 * 24 */ 25 26#include "netxen_nic_hw.h" 27#include "netxen_nic.h" 28 29#define NXHAL_VERSION 1 30 31static u32 32netxen_poll_rsp(struct netxen_adapter *adapter) 33{ 34 u32 rsp = NX_CDRP_RSP_OK; 35 int timeout = 0; 36 37 do { 38 /* give atleast 1ms for firmware to respond */ 39 msleep(1); 40 41 if (++timeout > NX_OS_CRB_RETRY_COUNT) 42 return NX_CDRP_RSP_TIMEOUT; 43 44 rsp = NXRD32(adapter, NX_CDRP_CRB_OFFSET); 45 } while (!NX_CDRP_IS_RSP(rsp)); 46 47 return rsp; 48} 49 50static u32 51netxen_issue_cmd(struct netxen_adapter *adapter, 52 u32 pci_fn, u32 version, u32 arg1, u32 arg2, u32 arg3, u32 cmd) 53{ 54 u32 rsp; 55 u32 signature = 0; 56 u32 rcode = NX_RCODE_SUCCESS; 57 58 signature = NX_CDRP_SIGNATURE_MAKE(pci_fn, version); 59 60 /* Acquire semaphore before accessing CRB */ 61 if (netxen_api_lock(adapter)) 62 return NX_RCODE_TIMEOUT; 63 64 NXWR32(adapter, NX_SIGN_CRB_OFFSET, signature); 65 66 NXWR32(adapter, NX_ARG1_CRB_OFFSET, arg1); 67 68 NXWR32(adapter, NX_ARG2_CRB_OFFSET, arg2); 69 70 NXWR32(adapter, NX_ARG3_CRB_OFFSET, arg3); 71 72 NXWR32(adapter, NX_CDRP_CRB_OFFSET, NX_CDRP_FORM_CMD(cmd)); 73 74 rsp = netxen_poll_rsp(adapter); 75 76 if (rsp == NX_CDRP_RSP_TIMEOUT) { 77 printk(KERN_ERR "%s: card response timeout.\n", 78 netxen_nic_driver_name); 79 80 rcode = NX_RCODE_TIMEOUT; 81 } else if (rsp == NX_CDRP_RSP_FAIL) { 82 rcode = NXRD32(adapter, NX_ARG1_CRB_OFFSET); 83 84 printk(KERN_ERR "%s: failed card response code:0x%x\n", 85 netxen_nic_driver_name, rcode); 86 } 87 88 /* Release semaphore */ 89 netxen_api_unlock(adapter); 90 91 return rcode; 92} 93 94int 95nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu) 96{ 97 u32 rcode = NX_RCODE_SUCCESS; 98 struct netxen_recv_context *recv_ctx = &adapter->recv_ctx; 99 100 if (recv_ctx->state == NX_HOST_CTX_STATE_ACTIVE) 101 rcode = netxen_issue_cmd(adapter, 102 adapter->ahw.pci_func, 103 NXHAL_VERSION, 104 recv_ctx->context_id, 105 mtu, 106 0, 107 NX_CDRP_CMD_SET_MTU); 108 109 if (rcode != NX_RCODE_SUCCESS) 110 return -EIO; 111 112 return 0; 113} 114 115static int 116nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter) 117{ 118 void *addr; 119 nx_hostrq_rx_ctx_t *prq; 120 nx_cardrsp_rx_ctx_t *prsp; 121 nx_hostrq_rds_ring_t *prq_rds; 122 nx_hostrq_sds_ring_t *prq_sds; 123 nx_cardrsp_rds_ring_t *prsp_rds; 124 nx_cardrsp_sds_ring_t *prsp_sds; 125 struct nx_host_rds_ring *rds_ring; 126 struct nx_host_sds_ring *sds_ring; 127 128 dma_addr_t hostrq_phys_addr, cardrsp_phys_addr; 129 u64 phys_addr; 130 131 int i, nrds_rings, nsds_rings; 132 size_t rq_size, rsp_size; 133 u32 cap, reg, val; 134 135 int err; 136 137 struct netxen_recv_context *recv_ctx = &adapter->recv_ctx; 138 139 nrds_rings = adapter->max_rds_rings; 140 nsds_rings = adapter->max_sds_rings; 141 142 rq_size = 143 SIZEOF_HOSTRQ_RX(nx_hostrq_rx_ctx_t, nrds_rings, nsds_rings); 144 rsp_size = 145 SIZEOF_CARDRSP_RX(nx_cardrsp_rx_ctx_t, nrds_rings, nsds_rings); 146 147 addr = pci_alloc_consistent(adapter->pdev, 148 rq_size, &hostrq_phys_addr); 149 if (addr == NULL) 150 return -ENOMEM; 151 prq = (nx_hostrq_rx_ctx_t *)addr; 152 153 addr = pci_alloc_consistent(adapter->pdev, 154 rsp_size, &cardrsp_phys_addr); 155 if (addr == NULL) { 156 err = -ENOMEM; 157 goto out_free_rq; 158 } 159 prsp = (nx_cardrsp_rx_ctx_t *)addr; 160 161 prq->host_rsp_dma_addr = cpu_to_le64(cardrsp_phys_addr); 162 163 cap = (NX_CAP0_LEGACY_CONTEXT | NX_CAP0_LEGACY_MN); 164 cap |= (NX_CAP0_JUMBO_CONTIGUOUS | NX_CAP0_LRO_CONTIGUOUS); 165 166 prq->capabilities[0] = cpu_to_le32(cap); 167 prq->host_int_crb_mode = 168 cpu_to_le32(NX_HOST_INT_CRB_MODE_SHARED); 169 prq->host_rds_crb_mode = 170 cpu_to_le32(NX_HOST_RDS_CRB_MODE_UNIQUE); 171 172 prq->num_rds_rings = cpu_to_le16(nrds_rings); 173 prq->num_sds_rings = cpu_to_le16(nsds_rings); 174 prq->rds_ring_offset = cpu_to_le32(0); 175 176 val = le32_to_cpu(prq->rds_ring_offset) + 177 (sizeof(nx_hostrq_rds_ring_t) * nrds_rings); 178 prq->sds_ring_offset = cpu_to_le32(val); 179 180 prq_rds = (nx_hostrq_rds_ring_t *)(prq->data + 181 le32_to_cpu(prq->rds_ring_offset)); 182 183 for (i = 0; i < nrds_rings; i++) { 184 185 rds_ring = &recv_ctx->rds_rings[i]; 186 187 prq_rds[i].host_phys_addr = cpu_to_le64(rds_ring->phys_addr); 188 prq_rds[i].ring_size = cpu_to_le32(rds_ring->num_desc); 189 prq_rds[i].ring_kind = cpu_to_le32(i); 190 prq_rds[i].buff_size = cpu_to_le64(rds_ring->dma_size); 191 } 192 193 prq_sds = (nx_hostrq_sds_ring_t *)(prq->data + 194 le32_to_cpu(prq->sds_ring_offset)); 195 196 for (i = 0; i < nsds_rings; i++) { 197 198 sds_ring = &recv_ctx->sds_rings[i]; 199 200 prq_sds[i].host_phys_addr = cpu_to_le64(sds_ring->phys_addr); 201 prq_sds[i].ring_size = cpu_to_le32(sds_ring->num_desc); 202 prq_sds[i].msi_index = cpu_to_le16(i); 203 } 204 205 phys_addr = hostrq_phys_addr; 206 err = netxen_issue_cmd(adapter, 207 adapter->ahw.pci_func, 208 NXHAL_VERSION, 209 (u32)(phys_addr >> 32), 210 (u32)(phys_addr & 0xffffffff), 211 rq_size, 212 NX_CDRP_CMD_CREATE_RX_CTX); 213 if (err) { 214 printk(KERN_WARNING 215 "Failed to create rx ctx in firmware%d\n", err); 216 goto out_free_rsp; 217 } 218 219 220 prsp_rds = ((nx_cardrsp_rds_ring_t *) 221 &prsp->data[le32_to_cpu(prsp->rds_ring_offset)]); 222 223 for (i = 0; i < le16_to_cpu(prsp->num_rds_rings); i++) { 224 rds_ring = &recv_ctx->rds_rings[i]; 225 226 reg = le32_to_cpu(prsp_rds[i].host_producer_crb); 227 rds_ring->crb_rcv_producer = netxen_get_ioaddr(adapter, 228 NETXEN_NIC_REG(reg - 0x200)); 229 } 230 231 prsp_sds = ((nx_cardrsp_sds_ring_t *) 232 &prsp->data[le32_to_cpu(prsp->sds_ring_offset)]); 233 234 for (i = 0; i < le16_to_cpu(prsp->num_sds_rings); i++) { 235 sds_ring = &recv_ctx->sds_rings[i]; 236 237 reg = le32_to_cpu(prsp_sds[i].host_consumer_crb); 238 sds_ring->crb_sts_consumer = netxen_get_ioaddr(adapter, 239 NETXEN_NIC_REG(reg - 0x200)); 240 241 reg = le32_to_cpu(prsp_sds[i].interrupt_crb); 242 sds_ring->crb_intr_mask = netxen_get_ioaddr(adapter, 243 NETXEN_NIC_REG(reg - 0x200)); 244 } 245 246 recv_ctx->state = le32_to_cpu(prsp->host_ctx_state); 247 recv_ctx->context_id = le16_to_cpu(prsp->context_id); 248 recv_ctx->virt_port = prsp->virt_port; 249 250out_free_rsp: 251 pci_free_consistent(adapter->pdev, rsp_size, prsp, cardrsp_phys_addr); 252out_free_rq: 253 pci_free_consistent(adapter->pdev, rq_size, prq, hostrq_phys_addr); 254 return err; 255} 256 257static void 258nx_fw_cmd_reset_ctx(struct netxen_adapter *adapter) 259{ 260 261 netxen_issue_cmd(adapter, adapter->ahw.pci_func, NXHAL_VERSION, 262 adapter->ahw.pci_func, NX_DESTROY_CTX_RESET, 0, 263 NX_CDRP_CMD_DESTROY_RX_CTX); 264 265 netxen_issue_cmd(adapter, adapter->ahw.pci_func, NXHAL_VERSION, 266 adapter->ahw.pci_func, NX_DESTROY_CTX_RESET, 0, 267 NX_CDRP_CMD_DESTROY_TX_CTX); 268} 269 270static void 271nx_fw_cmd_destroy_rx_ctx(struct netxen_adapter *adapter) 272{ 273 struct netxen_recv_context *recv_ctx = &adapter->recv_ctx; 274 275 if (netxen_issue_cmd(adapter, 276 adapter->ahw.pci_func, 277 NXHAL_VERSION, 278 recv_ctx->context_id, 279 NX_DESTROY_CTX_RESET, 280 0, 281 NX_CDRP_CMD_DESTROY_RX_CTX)) { 282 283 printk(KERN_WARNING 284 "%s: Failed to destroy rx ctx in firmware\n", 285 netxen_nic_driver_name); 286 } 287} 288 289static int 290nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter) 291{ 292 nx_hostrq_tx_ctx_t *prq; 293 nx_hostrq_cds_ring_t *prq_cds; 294 nx_cardrsp_tx_ctx_t *prsp; 295 void *rq_addr, *rsp_addr; 296 size_t rq_size, rsp_size; 297 u32 temp; 298 int err = 0; 299 u64 offset, phys_addr; 300 dma_addr_t rq_phys_addr, rsp_phys_addr; 301 struct nx_host_tx_ring *tx_ring = adapter->tx_ring; 302 struct netxen_recv_context *recv_ctx = &adapter->recv_ctx; 303 304 rq_size = SIZEOF_HOSTRQ_TX(nx_hostrq_tx_ctx_t); 305 rq_addr = pci_alloc_consistent(adapter->pdev, 306 rq_size, &rq_phys_addr); 307 if (!rq_addr) 308 return -ENOMEM; 309 310 rsp_size = SIZEOF_CARDRSP_TX(nx_cardrsp_tx_ctx_t); 311 rsp_addr = pci_alloc_consistent(adapter->pdev, 312 rsp_size, &rsp_phys_addr); 313 if (!rsp_addr) { 314 err = -ENOMEM; 315 goto out_free_rq; 316 } 317 318 memset(rq_addr, 0, rq_size); 319 prq = (nx_hostrq_tx_ctx_t *)rq_addr; 320 321 memset(rsp_addr, 0, rsp_size); 322 prsp = (nx_cardrsp_tx_ctx_t *)rsp_addr; 323 324 prq->host_rsp_dma_addr = cpu_to_le64(rsp_phys_addr); 325 326 temp = (NX_CAP0_LEGACY_CONTEXT | NX_CAP0_LEGACY_MN | NX_CAP0_LSO); 327 prq->capabilities[0] = cpu_to_le32(temp); 328 329 prq->host_int_crb_mode = 330 cpu_to_le32(NX_HOST_INT_CRB_MODE_SHARED); 331 332 prq->interrupt_ctl = 0; 333 prq->msi_index = 0; 334 335 prq->dummy_dma_addr = cpu_to_le64(adapter->dummy_dma.phys_addr); 336 337 offset = recv_ctx->phys_addr + sizeof(struct netxen_ring_ctx); 338 prq->cmd_cons_dma_addr = cpu_to_le64(offset); 339 340 prq_cds = &prq->cds_ring; 341 342 prq_cds->host_phys_addr = cpu_to_le64(tx_ring->phys_addr); 343 prq_cds->ring_size = cpu_to_le32(tx_ring->num_desc); 344 345 phys_addr = rq_phys_addr; 346 err = netxen_issue_cmd(adapter, 347 adapter->ahw.pci_func, 348 NXHAL_VERSION, 349 (u32)(phys_addr >> 32), 350 ((u32)phys_addr & 0xffffffff), 351 rq_size, 352 NX_CDRP_CMD_CREATE_TX_CTX); 353 354 if (err == NX_RCODE_SUCCESS) { 355 temp = le32_to_cpu(prsp->cds_ring.host_producer_crb); 356 tx_ring->crb_cmd_producer = netxen_get_ioaddr(adapter, 357 NETXEN_NIC_REG(temp - 0x200)); 358 adapter->tx_context_id = 359 le16_to_cpu(prsp->context_id); 360 } else { 361 printk(KERN_WARNING 362 "Failed to create tx ctx in firmware%d\n", err); 363 err = -EIO; 364 } 365 366 pci_free_consistent(adapter->pdev, rsp_size, rsp_addr, rsp_phys_addr); 367 368out_free_rq: 369 pci_free_consistent(adapter->pdev, rq_size, rq_addr, rq_phys_addr); 370 371 return err; 372} 373 374static void 375nx_fw_cmd_destroy_tx_ctx(struct netxen_adapter *adapter) 376{ 377 if (netxen_issue_cmd(adapter, 378 adapter->ahw.pci_func, 379 NXHAL_VERSION, 380 adapter->tx_context_id, 381 NX_DESTROY_CTX_RESET, 382 0, 383 NX_CDRP_CMD_DESTROY_TX_CTX)) { 384 385 printk(KERN_WARNING 386 "%s: Failed to destroy tx ctx in firmware\n", 387 netxen_nic_driver_name); 388 } 389} 390 391int 392nx_fw_cmd_query_phy(struct netxen_adapter *adapter, u32 reg, u32 *val) 393{ 394 u32 rcode; 395 396 rcode = netxen_issue_cmd(adapter, 397 adapter->ahw.pci_func, 398 NXHAL_VERSION, 399 reg, 400 0, 401 0, 402 NX_CDRP_CMD_READ_PHY); 403 404 if (rcode != NX_RCODE_SUCCESS) 405 return -EIO; 406 407 return NXRD32(adapter, NX_ARG1_CRB_OFFSET); 408} 409 410int 411nx_fw_cmd_set_phy(struct netxen_adapter *adapter, u32 reg, u32 val) 412{ 413 u32 rcode; 414 415 rcode = netxen_issue_cmd(adapter, 416 adapter->ahw.pci_func, 417 NXHAL_VERSION, 418 reg, 419 val, 420 0, 421 NX_CDRP_CMD_WRITE_PHY); 422 423 if (rcode != NX_RCODE_SUCCESS) 424 return -EIO; 425 426 return 0; 427} 428 429static u64 ctx_addr_sig_regs[][3] = { 430 {NETXEN_NIC_REG(0x188), NETXEN_NIC_REG(0x18c), NETXEN_NIC_REG(0x1c0)}, 431 {NETXEN_NIC_REG(0x190), NETXEN_NIC_REG(0x194), NETXEN_NIC_REG(0x1c4)}, 432 {NETXEN_NIC_REG(0x198), NETXEN_NIC_REG(0x19c), NETXEN_NIC_REG(0x1c8)}, 433 {NETXEN_NIC_REG(0x1a0), NETXEN_NIC_REG(0x1a4), NETXEN_NIC_REG(0x1cc)} 434}; 435 436#define CRB_CTX_ADDR_REG_LO(FUNC_ID) (ctx_addr_sig_regs[FUNC_ID][0]) 437#define CRB_CTX_ADDR_REG_HI(FUNC_ID) (ctx_addr_sig_regs[FUNC_ID][2]) 438#define CRB_CTX_SIGNATURE_REG(FUNC_ID) (ctx_addr_sig_regs[FUNC_ID][1]) 439 440#define lower32(x) ((u32)((x) & 0xffffffff)) 441#define upper32(x) ((u32)(((u64)(x) >> 32) & 0xffffffff)) 442 443static struct netxen_recv_crb recv_crb_registers[] = { 444 /* Instance 0 */ 445 { 446 /* crb_rcv_producer: */ 447 { 448 NETXEN_NIC_REG(0x100), 449 /* Jumbo frames */ 450 NETXEN_NIC_REG(0x110), 451 /* LRO */ 452 NETXEN_NIC_REG(0x120) 453 }, 454 /* crb_sts_consumer: */ 455 { 456 NETXEN_NIC_REG(0x138), 457 NETXEN_NIC_REG_2(0x000), 458 NETXEN_NIC_REG_2(0x004), 459 NETXEN_NIC_REG_2(0x008), 460 }, 461 /* sw_int_mask */ 462 { 463 CRB_SW_INT_MASK_0, 464 NETXEN_NIC_REG_2(0x044), 465 NETXEN_NIC_REG_2(0x048), 466 NETXEN_NIC_REG_2(0x04c), 467 }, 468 }, 469 /* Instance 1 */ 470 { 471 /* crb_rcv_producer: */ 472 { 473 NETXEN_NIC_REG(0x144), 474 /* Jumbo frames */ 475 NETXEN_NIC_REG(0x154), 476 /* LRO */ 477 NETXEN_NIC_REG(0x164) 478 }, 479 /* crb_sts_consumer: */ 480 { 481 NETXEN_NIC_REG(0x17c), 482 NETXEN_NIC_REG_2(0x020), 483 NETXEN_NIC_REG_2(0x024), 484 NETXEN_NIC_REG_2(0x028), 485 }, 486 /* sw_int_mask */ 487 { 488 CRB_SW_INT_MASK_1, 489 NETXEN_NIC_REG_2(0x064), 490 NETXEN_NIC_REG_2(0x068), 491 NETXEN_NIC_REG_2(0x06c), 492 }, 493 }, 494 /* Instance 2 */ 495 { 496 /* crb_rcv_producer: */ 497 { 498 NETXEN_NIC_REG(0x1d8), 499 /* Jumbo frames */ 500 NETXEN_NIC_REG(0x1f8), 501 /* LRO */ 502 NETXEN_NIC_REG(0x208) 503 }, 504 /* crb_sts_consumer: */ 505 { 506 NETXEN_NIC_REG(0x220), 507 NETXEN_NIC_REG_2(0x03c), 508 NETXEN_NIC_REG_2(0x03c), 509 NETXEN_NIC_REG_2(0x03c), 510 }, 511 /* sw_int_mask */ 512 { 513 CRB_SW_INT_MASK_2, 514 NETXEN_NIC_REG_2(0x03c), 515 NETXEN_NIC_REG_2(0x03c), 516 NETXEN_NIC_REG_2(0x03c), 517 }, 518 }, 519 /* Instance 3 */ 520 { 521 /* crb_rcv_producer: */ 522 { 523 NETXEN_NIC_REG(0x22c), 524 /* Jumbo frames */ 525 NETXEN_NIC_REG(0x23c), 526 /* LRO */ 527 NETXEN_NIC_REG(0x24c) 528 }, 529 /* crb_sts_consumer: */ 530 { 531 NETXEN_NIC_REG(0x264), 532 NETXEN_NIC_REG_2(0x03c), 533 NETXEN_NIC_REG_2(0x03c), 534 NETXEN_NIC_REG_2(0x03c), 535 }, 536 /* sw_int_mask */ 537 { 538 CRB_SW_INT_MASK_3, 539 NETXEN_NIC_REG_2(0x03c), 540 NETXEN_NIC_REG_2(0x03c), 541 NETXEN_NIC_REG_2(0x03c), 542 }, 543 }, 544}; 545 546static int 547netxen_init_old_ctx(struct netxen_adapter *adapter) 548{ 549 struct netxen_recv_context *recv_ctx; 550 struct nx_host_rds_ring *rds_ring; 551 struct nx_host_sds_ring *sds_ring; 552 struct nx_host_tx_ring *tx_ring; 553 int ring; 554 int port = adapter->portnum; 555 struct netxen_ring_ctx *hwctx; 556 u32 signature; 557 558 tx_ring = adapter->tx_ring; 559 recv_ctx = &adapter->recv_ctx; 560 hwctx = recv_ctx->hwctx; 561 562 hwctx->cmd_ring_addr = cpu_to_le64(tx_ring->phys_addr); 563 hwctx->cmd_ring_size = cpu_to_le32(tx_ring->num_desc); 564 565 566 for (ring = 0; ring < adapter->max_rds_rings; ring++) { 567 rds_ring = &recv_ctx->rds_rings[ring]; 568 569 hwctx->rcv_rings[ring].addr = 570 cpu_to_le64(rds_ring->phys_addr); 571 hwctx->rcv_rings[ring].size = 572 cpu_to_le32(rds_ring->num_desc); 573 } 574 575 for (ring = 0; ring < adapter->max_sds_rings; ring++) { 576 sds_ring = &recv_ctx->sds_rings[ring]; 577 578 if (ring == 0) { 579 hwctx->sts_ring_addr = cpu_to_le64(sds_ring->phys_addr); 580 hwctx->sts_ring_size = cpu_to_le32(sds_ring->num_desc); 581 } 582 hwctx->sts_rings[ring].addr = cpu_to_le64(sds_ring->phys_addr); 583 hwctx->sts_rings[ring].size = cpu_to_le32(sds_ring->num_desc); 584 hwctx->sts_rings[ring].msi_index = cpu_to_le16(ring); 585 } 586 hwctx->sts_ring_count = cpu_to_le32(adapter->max_sds_rings); 587 588 signature = (adapter->max_sds_rings > 1) ? 589 NETXEN_CTX_SIGNATURE_V2 : NETXEN_CTX_SIGNATURE; 590 591 NXWR32(adapter, CRB_CTX_ADDR_REG_LO(port), 592 lower32(recv_ctx->phys_addr)); 593 NXWR32(adapter, CRB_CTX_ADDR_REG_HI(port), 594 upper32(recv_ctx->phys_addr)); 595 NXWR32(adapter, CRB_CTX_SIGNATURE_REG(port), 596 signature | port); 597 return 0; 598} 599 600int netxen_alloc_hw_resources(struct netxen_adapter *adapter) 601{ 602 void *addr; 603 int err = 0; 604 int ring; 605 struct netxen_recv_context *recv_ctx; 606 struct nx_host_rds_ring *rds_ring; 607 struct nx_host_sds_ring *sds_ring; 608 struct nx_host_tx_ring *tx_ring; 609 610 struct pci_dev *pdev = adapter->pdev; 611 struct net_device *netdev = adapter->netdev; 612 int port = adapter->portnum; 613 614 recv_ctx = &adapter->recv_ctx; 615 tx_ring = adapter->tx_ring; 616 617 addr = pci_alloc_consistent(pdev, 618 sizeof(struct netxen_ring_ctx) + sizeof(uint32_t), 619 &recv_ctx->phys_addr); 620 if (addr == NULL) { 621 dev_err(&pdev->dev, "failed to allocate hw context\n"); 622 return -ENOMEM; 623 } 624 625 memset(addr, 0, sizeof(struct netxen_ring_ctx)); 626 recv_ctx->hwctx = (struct netxen_ring_ctx *)addr; 627 recv_ctx->hwctx->ctx_id = cpu_to_le32(port); 628 recv_ctx->hwctx->cmd_consumer_offset = 629 cpu_to_le64(recv_ctx->phys_addr + 630 sizeof(struct netxen_ring_ctx)); 631 tx_ring->hw_consumer = 632 (__le32 *)(((char *)addr) + sizeof(struct netxen_ring_ctx)); 633 634 /* cmd desc ring */ 635 addr = pci_alloc_consistent(pdev, TX_DESC_RINGSIZE(tx_ring), 636 &tx_ring->phys_addr); 637 638 if (addr == NULL) { 639 dev_err(&pdev->dev, "%s: failed to allocate tx desc ring\n", 640 netdev->name); 641 err = -ENOMEM; 642 goto err_out_free; 643 } 644 645 tx_ring->desc_head = (struct cmd_desc_type0 *)addr; 646 647 for (ring = 0; ring < adapter->max_rds_rings; ring++) { 648 rds_ring = &recv_ctx->rds_rings[ring]; 649 addr = pci_alloc_consistent(adapter->pdev, 650 RCV_DESC_RINGSIZE(rds_ring), 651 &rds_ring->phys_addr); 652 if (addr == NULL) { 653 dev_err(&pdev->dev, 654 "%s: failed to allocate rds ring [%d]\n", 655 netdev->name, ring); 656 err = -ENOMEM; 657 goto err_out_free; 658 } 659 rds_ring->desc_head = (struct rcv_desc *)addr; 660 661 if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) 662 rds_ring->crb_rcv_producer = 663 netxen_get_ioaddr(adapter, 664 recv_crb_registers[port].crb_rcv_producer[ring]); 665 } 666 667 for (ring = 0; ring < adapter->max_sds_rings; ring++) { 668 sds_ring = &recv_ctx->sds_rings[ring]; 669 670 addr = pci_alloc_consistent(adapter->pdev, 671 STATUS_DESC_RINGSIZE(sds_ring), 672 &sds_ring->phys_addr); 673 if (addr == NULL) { 674 dev_err(&pdev->dev, 675 "%s: failed to allocate sds ring [%d]\n", 676 netdev->name, ring); 677 err = -ENOMEM; 678 goto err_out_free; 679 } 680 sds_ring->desc_head = (struct status_desc *)addr; 681 682 if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { 683 sds_ring->crb_sts_consumer = 684 netxen_get_ioaddr(adapter, 685 recv_crb_registers[port].crb_sts_consumer[ring]); 686 687 sds_ring->crb_intr_mask = 688 netxen_get_ioaddr(adapter, 689 recv_crb_registers[port].sw_int_mask[ring]); 690 } 691 } 692 693 694 if (!NX_IS_REVISION_P2(adapter->ahw.revision_id)) { 695 if (test_and_set_bit(__NX_FW_ATTACHED, &adapter->state)) 696 goto done; 697 if (reset_devices) 698 nx_fw_cmd_reset_ctx(adapter); 699 err = nx_fw_cmd_create_rx_ctx(adapter); 700 if (err) 701 goto err_out_free; 702 err = nx_fw_cmd_create_tx_ctx(adapter); 703 if (err) 704 goto err_out_free; 705 } else { 706 err = netxen_init_old_ctx(adapter); 707 if (err) 708 goto err_out_free; 709 } 710 711done: 712 return 0; 713 714err_out_free: 715 netxen_free_hw_resources(adapter); 716 return err; 717} 718 719void netxen_free_hw_resources(struct netxen_adapter *adapter) 720{ 721 struct netxen_recv_context *recv_ctx; 722 struct nx_host_rds_ring *rds_ring; 723 struct nx_host_sds_ring *sds_ring; 724 struct nx_host_tx_ring *tx_ring; 725 int ring; 726 727 int port = adapter->portnum; 728 729 if (!NX_IS_REVISION_P2(adapter->ahw.revision_id)) { 730 if (!test_and_clear_bit(__NX_FW_ATTACHED, &adapter->state)) 731 goto done; 732 733 nx_fw_cmd_destroy_rx_ctx(adapter); 734 nx_fw_cmd_destroy_tx_ctx(adapter); 735 } else { 736 netxen_api_lock(adapter); 737 NXWR32(adapter, CRB_CTX_SIGNATURE_REG(port), 738 NETXEN_CTX_D3_RESET | port); 739 netxen_api_unlock(adapter); 740 } 741 742 /* Allow dma queues to drain after context reset */ 743 msleep(20); 744 745done: 746 recv_ctx = &adapter->recv_ctx; 747 748 if (recv_ctx->hwctx != NULL) { 749 pci_free_consistent(adapter->pdev, 750 sizeof(struct netxen_ring_ctx) + 751 sizeof(uint32_t), 752 recv_ctx->hwctx, 753 recv_ctx->phys_addr); 754 recv_ctx->hwctx = NULL; 755 } 756 757 tx_ring = adapter->tx_ring; 758 if (tx_ring->desc_head != NULL) { 759 pci_free_consistent(adapter->pdev, 760 TX_DESC_RINGSIZE(tx_ring), 761 tx_ring->desc_head, tx_ring->phys_addr); 762 tx_ring->desc_head = NULL; 763 } 764 765 for (ring = 0; ring < adapter->max_rds_rings; ring++) { 766 rds_ring = &recv_ctx->rds_rings[ring]; 767 768 if (rds_ring->desc_head != NULL) { 769 pci_free_consistent(adapter->pdev, 770 RCV_DESC_RINGSIZE(rds_ring), 771 rds_ring->desc_head, 772 rds_ring->phys_addr); 773 rds_ring->desc_head = NULL; 774 } 775 } 776 777 for (ring = 0; ring < adapter->max_sds_rings; ring++) { 778 sds_ring = &recv_ctx->sds_rings[ring]; 779 780 if (sds_ring->desc_head != NULL) { 781 pci_free_consistent(adapter->pdev, 782 STATUS_DESC_RINGSIZE(sds_ring), 783 sds_ring->desc_head, 784 sds_ring->phys_addr); 785 sds_ring->desc_head = NULL; 786 } 787 } 788} 789