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