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