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, see <http://www.gnu.org/licenses/>. 18 * 19 * The full GNU General Public License is included in this distribution 20 * in the file called "COPYING". 21 * 22 */ 23 24 #include "netxen_nic_hw.h" 25 #include "netxen_nic.h" 26 27 #define NXHAL_VERSION 1 28 29 static u32 30 netxen_poll_rsp(struct netxen_adapter *adapter) 31 { 32 u32 rsp = NX_CDRP_RSP_OK; 33 int timeout = 0; 34 35 do { 36 /* give atleast 1ms for firmware to respond */ 37 msleep(1); 38 39 if (++timeout > NX_OS_CRB_RETRY_COUNT) 40 return NX_CDRP_RSP_TIMEOUT; 41 42 rsp = NXRD32(adapter, NX_CDRP_CRB_OFFSET); 43 } while (!NX_CDRP_IS_RSP(rsp)); 44 45 return rsp; 46 } 47 48 static u32 49 netxen_issue_cmd(struct netxen_adapter *adapter, struct netxen_cmd_args *cmd) 50 { 51 u32 rsp; 52 u32 signature = 0; 53 u32 rcode = NX_RCODE_SUCCESS; 54 55 signature = NX_CDRP_SIGNATURE_MAKE(adapter->ahw.pci_func, 56 NXHAL_VERSION); 57 /* Acquire semaphore before accessing CRB */ 58 if (netxen_api_lock(adapter)) 59 return NX_RCODE_TIMEOUT; 60 61 NXWR32(adapter, NX_SIGN_CRB_OFFSET, signature); 62 63 NXWR32(adapter, NX_ARG1_CRB_OFFSET, cmd->req.arg1); 64 65 NXWR32(adapter, NX_ARG2_CRB_OFFSET, cmd->req.arg2); 66 67 NXWR32(adapter, NX_ARG3_CRB_OFFSET, cmd->req.arg3); 68 69 NXWR32(adapter, NX_CDRP_CRB_OFFSET, NX_CDRP_FORM_CMD(cmd->req.cmd)); 70 71 rsp = netxen_poll_rsp(adapter); 72 73 if (rsp == NX_CDRP_RSP_TIMEOUT) { 74 printk(KERN_ERR "%s: card response timeout.\n", 75 netxen_nic_driver_name); 76 77 rcode = NX_RCODE_TIMEOUT; 78 } else if (rsp == NX_CDRP_RSP_FAIL) { 79 rcode = NXRD32(adapter, NX_ARG1_CRB_OFFSET); 80 81 printk(KERN_ERR "%s: failed card response code:0x%x\n", 82 netxen_nic_driver_name, rcode); 83 } else if (rsp == NX_CDRP_RSP_OK) { 84 cmd->rsp.cmd = NX_RCODE_SUCCESS; 85 if (cmd->rsp.arg2) 86 cmd->rsp.arg2 = NXRD32(adapter, NX_ARG2_CRB_OFFSET); 87 if (cmd->rsp.arg3) 88 cmd->rsp.arg3 = NXRD32(adapter, NX_ARG3_CRB_OFFSET); 89 } 90 91 if (cmd->rsp.arg1) 92 cmd->rsp.arg1 = NXRD32(adapter, NX_ARG1_CRB_OFFSET); 93 /* Release semaphore */ 94 netxen_api_unlock(adapter); 95 96 return rcode; 97 } 98 99 static int 100 netxen_get_minidump_template_size(struct netxen_adapter *adapter) 101 { 102 struct netxen_cmd_args cmd; 103 memset(&cmd, 0, sizeof(cmd)); 104 cmd.req.cmd = NX_CDRP_CMD_TEMP_SIZE; 105 memset(&cmd.rsp, 1, sizeof(struct _cdrp_cmd)); 106 netxen_issue_cmd(adapter, &cmd); 107 if (cmd.rsp.cmd != NX_RCODE_SUCCESS) { 108 dev_info(&adapter->pdev->dev, 109 "Can't get template size %d\n", cmd.rsp.cmd); 110 return -EIO; 111 } 112 adapter->mdump.md_template_size = cmd.rsp.arg2; 113 adapter->mdump.md_template_ver = cmd.rsp.arg3; 114 return 0; 115 } 116 117 static int 118 netxen_get_minidump_template(struct netxen_adapter *adapter) 119 { 120 dma_addr_t md_template_addr; 121 void *addr; 122 u32 size; 123 struct netxen_cmd_args cmd; 124 size = adapter->mdump.md_template_size; 125 126 if (size == 0) { 127 dev_err(&adapter->pdev->dev, "Can not capture Minidump " 128 "template. Invalid template size.\n"); 129 return NX_RCODE_INVALID_ARGS; 130 } 131 132 addr = pci_alloc_consistent(adapter->pdev, size, &md_template_addr); 133 134 if (!addr) { 135 dev_err(&adapter->pdev->dev, "Unable to allocate dmable memory for template.\n"); 136 return -ENOMEM; 137 } 138 139 memset(addr, 0, size); 140 memset(&cmd, 0, sizeof(cmd)); 141 memset(&cmd.rsp, 1, sizeof(struct _cdrp_cmd)); 142 cmd.req.cmd = NX_CDRP_CMD_GET_TEMP_HDR; 143 cmd.req.arg1 = LSD(md_template_addr); 144 cmd.req.arg2 = MSD(md_template_addr); 145 cmd.req.arg3 |= size; 146 netxen_issue_cmd(adapter, &cmd); 147 148 if ((cmd.rsp.cmd == NX_RCODE_SUCCESS) && (size == cmd.rsp.arg2)) { 149 memcpy(adapter->mdump.md_template, addr, size); 150 } else { 151 dev_err(&adapter->pdev->dev, "Failed to get minidump template, " 152 "err_code : %d, requested_size : %d, actual_size : %d\n ", 153 cmd.rsp.cmd, size, cmd.rsp.arg2); 154 } 155 pci_free_consistent(adapter->pdev, size, addr, md_template_addr); 156 return 0; 157 } 158 159 static u32 160 netxen_check_template_checksum(struct netxen_adapter *adapter) 161 { 162 u64 sum = 0 ; 163 u32 *buff = adapter->mdump.md_template; 164 int count = adapter->mdump.md_template_size/sizeof(uint32_t) ; 165 166 while (count-- > 0) 167 sum += *buff++ ; 168 while (sum >> 32) 169 sum = (sum & 0xFFFFFFFF) + (sum >> 32) ; 170 171 return ~sum; 172 } 173 174 int 175 netxen_setup_minidump(struct netxen_adapter *adapter) 176 { 177 int err = 0, i; 178 u32 *template, *tmp_buf; 179 struct netxen_minidump_template_hdr *hdr; 180 err = netxen_get_minidump_template_size(adapter); 181 if (err) { 182 adapter->mdump.fw_supports_md = 0; 183 if ((err == NX_RCODE_CMD_INVALID) || 184 (err == NX_RCODE_CMD_NOT_IMPL)) { 185 dev_info(&adapter->pdev->dev, 186 "Flashed firmware version does not support minidump, " 187 "minimum version required is [ %u.%u.%u ].\n ", 188 NX_MD_SUPPORT_MAJOR, NX_MD_SUPPORT_MINOR, 189 NX_MD_SUPPORT_SUBVERSION); 190 } 191 return err; 192 } 193 194 if (!adapter->mdump.md_template_size) { 195 dev_err(&adapter->pdev->dev, "Error : Invalid template size " 196 ",should be non-zero.\n"); 197 return -EIO; 198 } 199 adapter->mdump.md_template = 200 kmalloc(adapter->mdump.md_template_size, GFP_KERNEL); 201 202 if (!adapter->mdump.md_template) 203 return -ENOMEM; 204 205 err = netxen_get_minidump_template(adapter); 206 if (err) { 207 if (err == NX_RCODE_CMD_NOT_IMPL) 208 adapter->mdump.fw_supports_md = 0; 209 goto free_template; 210 } 211 212 if (netxen_check_template_checksum(adapter)) { 213 dev_err(&adapter->pdev->dev, "Minidump template checksum Error\n"); 214 err = -EIO; 215 goto free_template; 216 } 217 218 adapter->mdump.md_capture_mask = NX_DUMP_MASK_DEF; 219 tmp_buf = (u32 *) adapter->mdump.md_template; 220 template = (u32 *) adapter->mdump.md_template; 221 for (i = 0; i < adapter->mdump.md_template_size/sizeof(u32); i++) 222 *template++ = __le32_to_cpu(*tmp_buf++); 223 hdr = (struct netxen_minidump_template_hdr *) 224 adapter->mdump.md_template; 225 adapter->mdump.md_capture_buff = NULL; 226 adapter->mdump.fw_supports_md = 1; 227 adapter->mdump.md_enabled = 0; 228 229 return err; 230 231 free_template: 232 kfree(adapter->mdump.md_template); 233 adapter->mdump.md_template = NULL; 234 return err; 235 } 236 237 238 int 239 nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu) 240 { 241 u32 rcode = NX_RCODE_SUCCESS; 242 struct netxen_recv_context *recv_ctx = &adapter->recv_ctx; 243 struct netxen_cmd_args cmd; 244 245 memset(&cmd, 0, sizeof(cmd)); 246 cmd.req.cmd = NX_CDRP_CMD_SET_MTU; 247 cmd.req.arg1 = recv_ctx->context_id; 248 cmd.req.arg2 = mtu; 249 cmd.req.arg3 = 0; 250 251 if (recv_ctx->state == NX_HOST_CTX_STATE_ACTIVE) 252 netxen_issue_cmd(adapter, &cmd); 253 254 if (rcode != NX_RCODE_SUCCESS) 255 return -EIO; 256 257 return 0; 258 } 259 260 int 261 nx_fw_cmd_set_gbe_port(struct netxen_adapter *adapter, 262 u32 speed, u32 duplex, u32 autoneg) 263 { 264 struct netxen_cmd_args cmd; 265 266 memset(&cmd, 0, sizeof(cmd)); 267 cmd.req.cmd = NX_CDRP_CMD_CONFIG_GBE_PORT; 268 cmd.req.arg1 = speed; 269 cmd.req.arg2 = duplex; 270 cmd.req.arg3 = autoneg; 271 return netxen_issue_cmd(adapter, &cmd); 272 } 273 274 static int 275 nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter) 276 { 277 void *addr; 278 nx_hostrq_rx_ctx_t *prq; 279 nx_cardrsp_rx_ctx_t *prsp; 280 nx_hostrq_rds_ring_t *prq_rds; 281 nx_hostrq_sds_ring_t *prq_sds; 282 nx_cardrsp_rds_ring_t *prsp_rds; 283 nx_cardrsp_sds_ring_t *prsp_sds; 284 struct nx_host_rds_ring *rds_ring; 285 struct nx_host_sds_ring *sds_ring; 286 struct netxen_cmd_args cmd; 287 288 dma_addr_t hostrq_phys_addr, cardrsp_phys_addr; 289 u64 phys_addr; 290 291 int i, nrds_rings, nsds_rings; 292 size_t rq_size, rsp_size; 293 u32 cap, reg, val; 294 295 int err; 296 297 struct netxen_recv_context *recv_ctx = &adapter->recv_ctx; 298 299 nrds_rings = adapter->max_rds_rings; 300 nsds_rings = adapter->max_sds_rings; 301 302 rq_size = 303 SIZEOF_HOSTRQ_RX(nx_hostrq_rx_ctx_t, nrds_rings, nsds_rings); 304 rsp_size = 305 SIZEOF_CARDRSP_RX(nx_cardrsp_rx_ctx_t, nrds_rings, nsds_rings); 306 307 addr = pci_alloc_consistent(adapter->pdev, 308 rq_size, &hostrq_phys_addr); 309 if (addr == NULL) 310 return -ENOMEM; 311 prq = addr; 312 313 addr = pci_alloc_consistent(adapter->pdev, 314 rsp_size, &cardrsp_phys_addr); 315 if (addr == NULL) { 316 err = -ENOMEM; 317 goto out_free_rq; 318 } 319 prsp = addr; 320 321 prq->host_rsp_dma_addr = cpu_to_le64(cardrsp_phys_addr); 322 323 cap = (NX_CAP0_LEGACY_CONTEXT | NX_CAP0_LEGACY_MN); 324 cap |= (NX_CAP0_JUMBO_CONTIGUOUS | NX_CAP0_LRO_CONTIGUOUS); 325 326 if (adapter->flags & NETXEN_FW_MSS_CAP) 327 cap |= NX_CAP0_HW_LRO_MSS; 328 329 prq->capabilities[0] = cpu_to_le32(cap); 330 prq->host_int_crb_mode = 331 cpu_to_le32(NX_HOST_INT_CRB_MODE_SHARED); 332 prq->host_rds_crb_mode = 333 cpu_to_le32(NX_HOST_RDS_CRB_MODE_UNIQUE); 334 335 prq->num_rds_rings = cpu_to_le16(nrds_rings); 336 prq->num_sds_rings = cpu_to_le16(nsds_rings); 337 prq->rds_ring_offset = cpu_to_le32(0); 338 339 val = le32_to_cpu(prq->rds_ring_offset) + 340 (sizeof(nx_hostrq_rds_ring_t) * nrds_rings); 341 prq->sds_ring_offset = cpu_to_le32(val); 342 343 prq_rds = (nx_hostrq_rds_ring_t *)(prq->data + 344 le32_to_cpu(prq->rds_ring_offset)); 345 346 for (i = 0; i < nrds_rings; i++) { 347 348 rds_ring = &recv_ctx->rds_rings[i]; 349 350 prq_rds[i].host_phys_addr = cpu_to_le64(rds_ring->phys_addr); 351 prq_rds[i].ring_size = cpu_to_le32(rds_ring->num_desc); 352 prq_rds[i].ring_kind = cpu_to_le32(i); 353 prq_rds[i].buff_size = cpu_to_le64(rds_ring->dma_size); 354 } 355 356 prq_sds = (nx_hostrq_sds_ring_t *)(prq->data + 357 le32_to_cpu(prq->sds_ring_offset)); 358 359 for (i = 0; i < nsds_rings; i++) { 360 361 sds_ring = &recv_ctx->sds_rings[i]; 362 363 prq_sds[i].host_phys_addr = cpu_to_le64(sds_ring->phys_addr); 364 prq_sds[i].ring_size = cpu_to_le32(sds_ring->num_desc); 365 prq_sds[i].msi_index = cpu_to_le16(i); 366 } 367 368 phys_addr = hostrq_phys_addr; 369 memset(&cmd, 0, sizeof(cmd)); 370 cmd.req.arg1 = (u32)(phys_addr >> 32); 371 cmd.req.arg2 = (u32)(phys_addr & 0xffffffff); 372 cmd.req.arg3 = rq_size; 373 cmd.req.cmd = NX_CDRP_CMD_CREATE_RX_CTX; 374 err = netxen_issue_cmd(adapter, &cmd); 375 if (err) { 376 printk(KERN_WARNING 377 "Failed to create rx ctx in firmware%d\n", err); 378 goto out_free_rsp; 379 } 380 381 382 prsp_rds = ((nx_cardrsp_rds_ring_t *) 383 &prsp->data[le32_to_cpu(prsp->rds_ring_offset)]); 384 385 for (i = 0; i < le16_to_cpu(prsp->num_rds_rings); i++) { 386 rds_ring = &recv_ctx->rds_rings[i]; 387 388 reg = le32_to_cpu(prsp_rds[i].host_producer_crb); 389 rds_ring->crb_rcv_producer = netxen_get_ioaddr(adapter, 390 NETXEN_NIC_REG(reg - 0x200)); 391 } 392 393 prsp_sds = ((nx_cardrsp_sds_ring_t *) 394 &prsp->data[le32_to_cpu(prsp->sds_ring_offset)]); 395 396 for (i = 0; i < le16_to_cpu(prsp->num_sds_rings); i++) { 397 sds_ring = &recv_ctx->sds_rings[i]; 398 399 reg = le32_to_cpu(prsp_sds[i].host_consumer_crb); 400 sds_ring->crb_sts_consumer = netxen_get_ioaddr(adapter, 401 NETXEN_NIC_REG(reg - 0x200)); 402 403 reg = le32_to_cpu(prsp_sds[i].interrupt_crb); 404 sds_ring->crb_intr_mask = netxen_get_ioaddr(adapter, 405 NETXEN_NIC_REG(reg - 0x200)); 406 } 407 408 recv_ctx->state = le32_to_cpu(prsp->host_ctx_state); 409 recv_ctx->context_id = le16_to_cpu(prsp->context_id); 410 recv_ctx->virt_port = prsp->virt_port; 411 412 out_free_rsp: 413 pci_free_consistent(adapter->pdev, rsp_size, prsp, cardrsp_phys_addr); 414 out_free_rq: 415 pci_free_consistent(adapter->pdev, rq_size, prq, hostrq_phys_addr); 416 return err; 417 } 418 419 static void 420 nx_fw_cmd_destroy_rx_ctx(struct netxen_adapter *adapter) 421 { 422 struct netxen_recv_context *recv_ctx = &adapter->recv_ctx; 423 struct netxen_cmd_args cmd; 424 425 memset(&cmd, 0, sizeof(cmd)); 426 cmd.req.arg1 = recv_ctx->context_id; 427 cmd.req.arg2 = NX_DESTROY_CTX_RESET; 428 cmd.req.arg3 = 0; 429 cmd.req.cmd = NX_CDRP_CMD_DESTROY_RX_CTX; 430 431 if (netxen_issue_cmd(adapter, &cmd)) { 432 printk(KERN_WARNING 433 "%s: Failed to destroy rx ctx in firmware\n", 434 netxen_nic_driver_name); 435 } 436 } 437 438 static int 439 nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter) 440 { 441 nx_hostrq_tx_ctx_t *prq; 442 nx_hostrq_cds_ring_t *prq_cds; 443 nx_cardrsp_tx_ctx_t *prsp; 444 void *rq_addr, *rsp_addr; 445 size_t rq_size, rsp_size; 446 u32 temp; 447 int err = 0; 448 u64 offset, phys_addr; 449 dma_addr_t rq_phys_addr, rsp_phys_addr; 450 struct nx_host_tx_ring *tx_ring = adapter->tx_ring; 451 struct netxen_recv_context *recv_ctx = &adapter->recv_ctx; 452 struct netxen_cmd_args cmd; 453 454 rq_size = SIZEOF_HOSTRQ_TX(nx_hostrq_tx_ctx_t); 455 rq_addr = pci_alloc_consistent(adapter->pdev, 456 rq_size, &rq_phys_addr); 457 if (!rq_addr) 458 return -ENOMEM; 459 460 rsp_size = SIZEOF_CARDRSP_TX(nx_cardrsp_tx_ctx_t); 461 rsp_addr = pci_alloc_consistent(adapter->pdev, 462 rsp_size, &rsp_phys_addr); 463 if (!rsp_addr) { 464 err = -ENOMEM; 465 goto out_free_rq; 466 } 467 468 memset(rq_addr, 0, rq_size); 469 prq = rq_addr; 470 471 memset(rsp_addr, 0, rsp_size); 472 prsp = rsp_addr; 473 474 prq->host_rsp_dma_addr = cpu_to_le64(rsp_phys_addr); 475 476 temp = (NX_CAP0_LEGACY_CONTEXT | NX_CAP0_LEGACY_MN | NX_CAP0_LSO); 477 prq->capabilities[0] = cpu_to_le32(temp); 478 479 prq->host_int_crb_mode = 480 cpu_to_le32(NX_HOST_INT_CRB_MODE_SHARED); 481 482 prq->interrupt_ctl = 0; 483 prq->msi_index = 0; 484 485 prq->dummy_dma_addr = cpu_to_le64(adapter->dummy_dma.phys_addr); 486 487 offset = recv_ctx->phys_addr + sizeof(struct netxen_ring_ctx); 488 prq->cmd_cons_dma_addr = cpu_to_le64(offset); 489 490 prq_cds = &prq->cds_ring; 491 492 prq_cds->host_phys_addr = cpu_to_le64(tx_ring->phys_addr); 493 prq_cds->ring_size = cpu_to_le32(tx_ring->num_desc); 494 495 phys_addr = rq_phys_addr; 496 memset(&cmd, 0, sizeof(cmd)); 497 cmd.req.arg1 = (u32)(phys_addr >> 32); 498 cmd.req.arg2 = ((u32)phys_addr & 0xffffffff); 499 cmd.req.arg3 = rq_size; 500 cmd.req.cmd = NX_CDRP_CMD_CREATE_TX_CTX; 501 err = netxen_issue_cmd(adapter, &cmd); 502 503 if (err == NX_RCODE_SUCCESS) { 504 temp = le32_to_cpu(prsp->cds_ring.host_producer_crb); 505 tx_ring->crb_cmd_producer = netxen_get_ioaddr(adapter, 506 NETXEN_NIC_REG(temp - 0x200)); 507 #if 0 508 adapter->tx_state = 509 le32_to_cpu(prsp->host_ctx_state); 510 #endif 511 adapter->tx_context_id = 512 le16_to_cpu(prsp->context_id); 513 } else { 514 printk(KERN_WARNING 515 "Failed to create tx ctx in firmware%d\n", err); 516 err = -EIO; 517 } 518 519 pci_free_consistent(adapter->pdev, rsp_size, rsp_addr, rsp_phys_addr); 520 521 out_free_rq: 522 pci_free_consistent(adapter->pdev, rq_size, rq_addr, rq_phys_addr); 523 524 return err; 525 } 526 527 static void 528 nx_fw_cmd_destroy_tx_ctx(struct netxen_adapter *adapter) 529 { 530 struct netxen_cmd_args cmd; 531 532 memset(&cmd, 0, sizeof(cmd)); 533 cmd.req.arg1 = adapter->tx_context_id; 534 cmd.req.arg2 = NX_DESTROY_CTX_RESET; 535 cmd.req.arg3 = 0; 536 cmd.req.cmd = NX_CDRP_CMD_DESTROY_TX_CTX; 537 if (netxen_issue_cmd(adapter, &cmd)) { 538 printk(KERN_WARNING 539 "%s: Failed to destroy tx ctx in firmware\n", 540 netxen_nic_driver_name); 541 } 542 } 543 544 int 545 nx_fw_cmd_query_phy(struct netxen_adapter *adapter, u32 reg, u32 *val) 546 { 547 u32 rcode; 548 struct netxen_cmd_args cmd; 549 550 memset(&cmd, 0, sizeof(cmd)); 551 cmd.req.arg1 = reg; 552 cmd.req.arg2 = 0; 553 cmd.req.arg3 = 0; 554 cmd.req.cmd = NX_CDRP_CMD_READ_PHY; 555 cmd.rsp.arg1 = 1; 556 rcode = netxen_issue_cmd(adapter, &cmd); 557 if (rcode != NX_RCODE_SUCCESS) 558 return -EIO; 559 560 if (val == NULL) 561 return -EIO; 562 563 *val = cmd.rsp.arg1; 564 return 0; 565 } 566 567 int 568 nx_fw_cmd_set_phy(struct netxen_adapter *adapter, u32 reg, u32 val) 569 { 570 u32 rcode; 571 struct netxen_cmd_args cmd; 572 573 memset(&cmd, 0, sizeof(cmd)); 574 cmd.req.arg1 = reg; 575 cmd.req.arg2 = val; 576 cmd.req.arg3 = 0; 577 cmd.req.cmd = NX_CDRP_CMD_WRITE_PHY; 578 rcode = netxen_issue_cmd(adapter, &cmd); 579 if (rcode != NX_RCODE_SUCCESS) 580 return -EIO; 581 582 return 0; 583 } 584 585 static u64 ctx_addr_sig_regs[][3] = { 586 {NETXEN_NIC_REG(0x188), NETXEN_NIC_REG(0x18c), NETXEN_NIC_REG(0x1c0)}, 587 {NETXEN_NIC_REG(0x190), NETXEN_NIC_REG(0x194), NETXEN_NIC_REG(0x1c4)}, 588 {NETXEN_NIC_REG(0x198), NETXEN_NIC_REG(0x19c), NETXEN_NIC_REG(0x1c8)}, 589 {NETXEN_NIC_REG(0x1a0), NETXEN_NIC_REG(0x1a4), NETXEN_NIC_REG(0x1cc)} 590 }; 591 592 #define CRB_CTX_ADDR_REG_LO(FUNC_ID) (ctx_addr_sig_regs[FUNC_ID][0]) 593 #define CRB_CTX_ADDR_REG_HI(FUNC_ID) (ctx_addr_sig_regs[FUNC_ID][2]) 594 #define CRB_CTX_SIGNATURE_REG(FUNC_ID) (ctx_addr_sig_regs[FUNC_ID][1]) 595 596 #define lower32(x) ((u32)((x) & 0xffffffff)) 597 #define upper32(x) ((u32)(((u64)(x) >> 32) & 0xffffffff)) 598 599 static struct netxen_recv_crb recv_crb_registers[] = { 600 /* Instance 0 */ 601 { 602 /* crb_rcv_producer: */ 603 { 604 NETXEN_NIC_REG(0x100), 605 /* Jumbo frames */ 606 NETXEN_NIC_REG(0x110), 607 /* LRO */ 608 NETXEN_NIC_REG(0x120) 609 }, 610 /* crb_sts_consumer: */ 611 { 612 NETXEN_NIC_REG(0x138), 613 NETXEN_NIC_REG_2(0x000), 614 NETXEN_NIC_REG_2(0x004), 615 NETXEN_NIC_REG_2(0x008), 616 }, 617 /* sw_int_mask */ 618 { 619 CRB_SW_INT_MASK_0, 620 NETXEN_NIC_REG_2(0x044), 621 NETXEN_NIC_REG_2(0x048), 622 NETXEN_NIC_REG_2(0x04c), 623 }, 624 }, 625 /* Instance 1 */ 626 { 627 /* crb_rcv_producer: */ 628 { 629 NETXEN_NIC_REG(0x144), 630 /* Jumbo frames */ 631 NETXEN_NIC_REG(0x154), 632 /* LRO */ 633 NETXEN_NIC_REG(0x164) 634 }, 635 /* crb_sts_consumer: */ 636 { 637 NETXEN_NIC_REG(0x17c), 638 NETXEN_NIC_REG_2(0x020), 639 NETXEN_NIC_REG_2(0x024), 640 NETXEN_NIC_REG_2(0x028), 641 }, 642 /* sw_int_mask */ 643 { 644 CRB_SW_INT_MASK_1, 645 NETXEN_NIC_REG_2(0x064), 646 NETXEN_NIC_REG_2(0x068), 647 NETXEN_NIC_REG_2(0x06c), 648 }, 649 }, 650 /* Instance 2 */ 651 { 652 /* crb_rcv_producer: */ 653 { 654 NETXEN_NIC_REG(0x1d8), 655 /* Jumbo frames */ 656 NETXEN_NIC_REG(0x1f8), 657 /* LRO */ 658 NETXEN_NIC_REG(0x208) 659 }, 660 /* crb_sts_consumer: */ 661 { 662 NETXEN_NIC_REG(0x220), 663 NETXEN_NIC_REG_2(0x03c), 664 NETXEN_NIC_REG_2(0x03c), 665 NETXEN_NIC_REG_2(0x03c), 666 }, 667 /* sw_int_mask */ 668 { 669 CRB_SW_INT_MASK_2, 670 NETXEN_NIC_REG_2(0x03c), 671 NETXEN_NIC_REG_2(0x03c), 672 NETXEN_NIC_REG_2(0x03c), 673 }, 674 }, 675 /* Instance 3 */ 676 { 677 /* crb_rcv_producer: */ 678 { 679 NETXEN_NIC_REG(0x22c), 680 /* Jumbo frames */ 681 NETXEN_NIC_REG(0x23c), 682 /* LRO */ 683 NETXEN_NIC_REG(0x24c) 684 }, 685 /* crb_sts_consumer: */ 686 { 687 NETXEN_NIC_REG(0x264), 688 NETXEN_NIC_REG_2(0x03c), 689 NETXEN_NIC_REG_2(0x03c), 690 NETXEN_NIC_REG_2(0x03c), 691 }, 692 /* sw_int_mask */ 693 { 694 CRB_SW_INT_MASK_3, 695 NETXEN_NIC_REG_2(0x03c), 696 NETXEN_NIC_REG_2(0x03c), 697 NETXEN_NIC_REG_2(0x03c), 698 }, 699 }, 700 }; 701 702 static int 703 netxen_init_old_ctx(struct netxen_adapter *adapter) 704 { 705 struct netxen_recv_context *recv_ctx; 706 struct nx_host_rds_ring *rds_ring; 707 struct nx_host_sds_ring *sds_ring; 708 struct nx_host_tx_ring *tx_ring; 709 int ring; 710 int port = adapter->portnum; 711 struct netxen_ring_ctx *hwctx; 712 u32 signature; 713 714 tx_ring = adapter->tx_ring; 715 recv_ctx = &adapter->recv_ctx; 716 hwctx = recv_ctx->hwctx; 717 718 hwctx->cmd_ring_addr = cpu_to_le64(tx_ring->phys_addr); 719 hwctx->cmd_ring_size = cpu_to_le32(tx_ring->num_desc); 720 721 722 for (ring = 0; ring < adapter->max_rds_rings; ring++) { 723 rds_ring = &recv_ctx->rds_rings[ring]; 724 725 hwctx->rcv_rings[ring].addr = 726 cpu_to_le64(rds_ring->phys_addr); 727 hwctx->rcv_rings[ring].size = 728 cpu_to_le32(rds_ring->num_desc); 729 } 730 731 for (ring = 0; ring < adapter->max_sds_rings; ring++) { 732 sds_ring = &recv_ctx->sds_rings[ring]; 733 734 if (ring == 0) { 735 hwctx->sts_ring_addr = cpu_to_le64(sds_ring->phys_addr); 736 hwctx->sts_ring_size = cpu_to_le32(sds_ring->num_desc); 737 } 738 hwctx->sts_rings[ring].addr = cpu_to_le64(sds_ring->phys_addr); 739 hwctx->sts_rings[ring].size = cpu_to_le32(sds_ring->num_desc); 740 hwctx->sts_rings[ring].msi_index = cpu_to_le16(ring); 741 } 742 hwctx->sts_ring_count = cpu_to_le32(adapter->max_sds_rings); 743 744 signature = (adapter->max_sds_rings > 1) ? 745 NETXEN_CTX_SIGNATURE_V2 : NETXEN_CTX_SIGNATURE; 746 747 NXWR32(adapter, CRB_CTX_ADDR_REG_LO(port), 748 lower32(recv_ctx->phys_addr)); 749 NXWR32(adapter, CRB_CTX_ADDR_REG_HI(port), 750 upper32(recv_ctx->phys_addr)); 751 NXWR32(adapter, CRB_CTX_SIGNATURE_REG(port), 752 signature | port); 753 return 0; 754 } 755 756 int netxen_alloc_hw_resources(struct netxen_adapter *adapter) 757 { 758 void *addr; 759 int err = 0; 760 int ring; 761 struct netxen_recv_context *recv_ctx; 762 struct nx_host_rds_ring *rds_ring; 763 struct nx_host_sds_ring *sds_ring; 764 struct nx_host_tx_ring *tx_ring; 765 766 struct pci_dev *pdev = adapter->pdev; 767 struct net_device *netdev = adapter->netdev; 768 int port = adapter->portnum; 769 770 recv_ctx = &adapter->recv_ctx; 771 tx_ring = adapter->tx_ring; 772 773 addr = pci_alloc_consistent(pdev, 774 sizeof(struct netxen_ring_ctx) + sizeof(uint32_t), 775 &recv_ctx->phys_addr); 776 if (addr == NULL) { 777 dev_err(&pdev->dev, "failed to allocate hw context\n"); 778 return -ENOMEM; 779 } 780 781 memset(addr, 0, sizeof(struct netxen_ring_ctx)); 782 recv_ctx->hwctx = addr; 783 recv_ctx->hwctx->ctx_id = cpu_to_le32(port); 784 recv_ctx->hwctx->cmd_consumer_offset = 785 cpu_to_le64(recv_ctx->phys_addr + 786 sizeof(struct netxen_ring_ctx)); 787 tx_ring->hw_consumer = 788 (__le32 *)(((char *)addr) + sizeof(struct netxen_ring_ctx)); 789 790 /* cmd desc ring */ 791 addr = pci_alloc_consistent(pdev, TX_DESC_RINGSIZE(tx_ring), 792 &tx_ring->phys_addr); 793 794 if (addr == NULL) { 795 dev_err(&pdev->dev, "%s: failed to allocate tx desc ring\n", 796 netdev->name); 797 err = -ENOMEM; 798 goto err_out_free; 799 } 800 801 tx_ring->desc_head = addr; 802 803 for (ring = 0; ring < adapter->max_rds_rings; ring++) { 804 rds_ring = &recv_ctx->rds_rings[ring]; 805 addr = pci_alloc_consistent(adapter->pdev, 806 RCV_DESC_RINGSIZE(rds_ring), 807 &rds_ring->phys_addr); 808 if (addr == NULL) { 809 dev_err(&pdev->dev, 810 "%s: failed to allocate rds ring [%d]\n", 811 netdev->name, ring); 812 err = -ENOMEM; 813 goto err_out_free; 814 } 815 rds_ring->desc_head = addr; 816 817 if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) 818 rds_ring->crb_rcv_producer = 819 netxen_get_ioaddr(adapter, 820 recv_crb_registers[port].crb_rcv_producer[ring]); 821 } 822 823 for (ring = 0; ring < adapter->max_sds_rings; ring++) { 824 sds_ring = &recv_ctx->sds_rings[ring]; 825 826 addr = pci_alloc_consistent(adapter->pdev, 827 STATUS_DESC_RINGSIZE(sds_ring), 828 &sds_ring->phys_addr); 829 if (addr == NULL) { 830 dev_err(&pdev->dev, 831 "%s: failed to allocate sds ring [%d]\n", 832 netdev->name, ring); 833 err = -ENOMEM; 834 goto err_out_free; 835 } 836 sds_ring->desc_head = addr; 837 838 if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { 839 sds_ring->crb_sts_consumer = 840 netxen_get_ioaddr(adapter, 841 recv_crb_registers[port].crb_sts_consumer[ring]); 842 843 sds_ring->crb_intr_mask = 844 netxen_get_ioaddr(adapter, 845 recv_crb_registers[port].sw_int_mask[ring]); 846 } 847 } 848 849 850 if (!NX_IS_REVISION_P2(adapter->ahw.revision_id)) { 851 if (test_and_set_bit(__NX_FW_ATTACHED, &adapter->state)) 852 goto done; 853 err = nx_fw_cmd_create_rx_ctx(adapter); 854 if (err) 855 goto err_out_free; 856 err = nx_fw_cmd_create_tx_ctx(adapter); 857 if (err) 858 goto err_out_free; 859 } else { 860 err = netxen_init_old_ctx(adapter); 861 if (err) 862 goto err_out_free; 863 } 864 865 done: 866 return 0; 867 868 err_out_free: 869 netxen_free_hw_resources(adapter); 870 return err; 871 } 872 873 void netxen_free_hw_resources(struct netxen_adapter *adapter) 874 { 875 struct netxen_recv_context *recv_ctx; 876 struct nx_host_rds_ring *rds_ring; 877 struct nx_host_sds_ring *sds_ring; 878 struct nx_host_tx_ring *tx_ring; 879 int ring; 880 881 int port = adapter->portnum; 882 883 if (!NX_IS_REVISION_P2(adapter->ahw.revision_id)) { 884 if (!test_and_clear_bit(__NX_FW_ATTACHED, &adapter->state)) 885 goto done; 886 887 nx_fw_cmd_destroy_rx_ctx(adapter); 888 nx_fw_cmd_destroy_tx_ctx(adapter); 889 } else { 890 netxen_api_lock(adapter); 891 NXWR32(adapter, CRB_CTX_SIGNATURE_REG(port), 892 NETXEN_CTX_D3_RESET | port); 893 netxen_api_unlock(adapter); 894 } 895 896 /* Allow dma queues to drain after context reset */ 897 msleep(20); 898 899 done: 900 recv_ctx = &adapter->recv_ctx; 901 902 if (recv_ctx->hwctx != NULL) { 903 pci_free_consistent(adapter->pdev, 904 sizeof(struct netxen_ring_ctx) + 905 sizeof(uint32_t), 906 recv_ctx->hwctx, 907 recv_ctx->phys_addr); 908 recv_ctx->hwctx = NULL; 909 } 910 911 tx_ring = adapter->tx_ring; 912 if (tx_ring->desc_head != NULL) { 913 pci_free_consistent(adapter->pdev, 914 TX_DESC_RINGSIZE(tx_ring), 915 tx_ring->desc_head, tx_ring->phys_addr); 916 tx_ring->desc_head = NULL; 917 } 918 919 for (ring = 0; ring < adapter->max_rds_rings; ring++) { 920 rds_ring = &recv_ctx->rds_rings[ring]; 921 922 if (rds_ring->desc_head != NULL) { 923 pci_free_consistent(adapter->pdev, 924 RCV_DESC_RINGSIZE(rds_ring), 925 rds_ring->desc_head, 926 rds_ring->phys_addr); 927 rds_ring->desc_head = NULL; 928 } 929 } 930 931 for (ring = 0; ring < adapter->max_sds_rings; ring++) { 932 sds_ring = &recv_ctx->sds_rings[ring]; 933 934 if (sds_ring->desc_head != NULL) { 935 pci_free_consistent(adapter->pdev, 936 STATUS_DESC_RINGSIZE(sds_ring), 937 sds_ring->desc_head, 938 sds_ring->phys_addr); 939 sds_ring->desc_head = NULL; 940 } 941 } 942 } 943 944