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