1/* 2 * Copyright (C) 2003 - 2006 NetXen, Inc. 3 * All rights reserved. 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License 7 * as published by the Free Software Foundation; either version 2 8 * of the License, or (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, but 11 * WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 18 * MA 02111-1307, USA. 19 * 20 * The full GNU General Public License is included in this distribution 21 * in the file called LICENSE. 22 * 23 * Contact Information: 24 * info@netxen.com 25 * NetXen, 26 * 3965 Freedom Circle, Fourth floor, 27 * Santa Clara, CA 95054 28 * 29 * 30 * Source file for NIC routines to access the Phantom hardware 31 * 32 */ 33 34#include "netxen_nic.h" 35#include "netxen_nic_hw.h" 36#define DEFINE_GLOBAL_RECV_CRB 37#include "netxen_nic_phan_reg.h" 38 39 40#include <net/ip.h> 41 42struct netxen_recv_crb recv_crb_registers[] = { 43 /* 44 * Instance 0. 45 */ 46 { 47 /* rcv_desc_crb: */ 48 { 49 { 50 /* crb_rcv_producer_offset: */ 51 NETXEN_NIC_REG(0x100), 52 /* crb_rcv_consumer_offset: */ 53 NETXEN_NIC_REG(0x104), 54 /* crb_gloablrcv_ring: */ 55 NETXEN_NIC_REG(0x108), 56 /* crb_rcv_ring_size */ 57 NETXEN_NIC_REG(0x10c), 58 59 }, 60 /* Jumbo frames */ 61 { 62 /* crb_rcv_producer_offset: */ 63 NETXEN_NIC_REG(0x110), 64 /* crb_rcv_consumer_offset: */ 65 NETXEN_NIC_REG(0x114), 66 /* crb_gloablrcv_ring: */ 67 NETXEN_NIC_REG(0x118), 68 /* crb_rcv_ring_size */ 69 NETXEN_NIC_REG(0x11c), 70 }, 71 /* LRO */ 72 { 73 /* crb_rcv_producer_offset: */ 74 NETXEN_NIC_REG(0x120), 75 /* crb_rcv_consumer_offset: */ 76 NETXEN_NIC_REG(0x124), 77 /* crb_gloablrcv_ring: */ 78 NETXEN_NIC_REG(0x128), 79 /* crb_rcv_ring_size */ 80 NETXEN_NIC_REG(0x12c), 81 } 82 }, 83 /* crb_rcvstatus_ring: */ 84 NETXEN_NIC_REG(0x130), 85 /* crb_rcv_status_producer: */ 86 NETXEN_NIC_REG(0x134), 87 /* crb_rcv_status_consumer: */ 88 NETXEN_NIC_REG(0x138), 89 /* crb_rcvpeg_state: */ 90 NETXEN_NIC_REG(0x13c), 91 /* crb_status_ring_size */ 92 NETXEN_NIC_REG(0x140), 93 94 }, 95 /* 96 * Instance 1, 97 */ 98 { 99 /* rcv_desc_crb: */ 100 { 101 { 102 /* crb_rcv_producer_offset: */ 103 NETXEN_NIC_REG(0x144), 104 /* crb_rcv_consumer_offset: */ 105 NETXEN_NIC_REG(0x148), 106 /* crb_globalrcv_ring: */ 107 NETXEN_NIC_REG(0x14c), 108 /* crb_rcv_ring_size */ 109 NETXEN_NIC_REG(0x150), 110 111 }, 112 /* Jumbo frames */ 113 { 114 /* crb_rcv_producer_offset: */ 115 NETXEN_NIC_REG(0x154), 116 /* crb_rcv_consumer_offset: */ 117 NETXEN_NIC_REG(0x158), 118 /* crb_globalrcv_ring: */ 119 NETXEN_NIC_REG(0x15c), 120 /* crb_rcv_ring_size */ 121 NETXEN_NIC_REG(0x160), 122 }, 123 /* LRO */ 124 { 125 /* crb_rcv_producer_offset: */ 126 NETXEN_NIC_REG(0x164), 127 /* crb_rcv_consumer_offset: */ 128 NETXEN_NIC_REG(0x168), 129 /* crb_globalrcv_ring: */ 130 NETXEN_NIC_REG(0x16c), 131 /* crb_rcv_ring_size */ 132 NETXEN_NIC_REG(0x170), 133 } 134 135 }, 136 /* crb_rcvstatus_ring: */ 137 NETXEN_NIC_REG(0x174), 138 /* crb_rcv_status_producer: */ 139 NETXEN_NIC_REG(0x178), 140 /* crb_rcv_status_consumer: */ 141 NETXEN_NIC_REG(0x17c), 142 /* crb_rcvpeg_state: */ 143 NETXEN_NIC_REG(0x180), 144 /* crb_status_ring_size */ 145 NETXEN_NIC_REG(0x184), 146 }, 147 /* 148 * Instance 2, 149 */ 150 { 151 { 152 { 153 /* crb_rcv_producer_offset: */ 154 NETXEN_NIC_REG(0x1d8), 155 /* crb_rcv_consumer_offset: */ 156 NETXEN_NIC_REG(0x1dc), 157 /* crb_gloablrcv_ring: */ 158 NETXEN_NIC_REG(0x1f0), 159 /* crb_rcv_ring_size */ 160 NETXEN_NIC_REG(0x1f4), 161 }, 162 /* Jumbo frames */ 163 { 164 /* crb_rcv_producer_offset: */ 165 NETXEN_NIC_REG(0x1f8), 166 /* crb_rcv_consumer_offset: */ 167 NETXEN_NIC_REG(0x1fc), 168 /* crb_gloablrcv_ring: */ 169 NETXEN_NIC_REG(0x200), 170 /* crb_rcv_ring_size */ 171 NETXEN_NIC_REG(0x204), 172 }, 173 /* LRO */ 174 { 175 /* crb_rcv_producer_offset: */ 176 NETXEN_NIC_REG(0x208), 177 /* crb_rcv_consumer_offset: */ 178 NETXEN_NIC_REG(0x20c), 179 /* crb_gloablrcv_ring: */ 180 NETXEN_NIC_REG(0x210), 181 /* crb_rcv_ring_size */ 182 NETXEN_NIC_REG(0x214), 183 } 184 }, 185 /* crb_rcvstatus_ring: */ 186 NETXEN_NIC_REG(0x218), 187 /* crb_rcv_status_producer: */ 188 NETXEN_NIC_REG(0x21c), 189 /* crb_rcv_status_consumer: */ 190 NETXEN_NIC_REG(0x220), 191 /* crb_rcvpeg_state: */ 192 NETXEN_NIC_REG(0x224), 193 /* crb_status_ring_size */ 194 NETXEN_NIC_REG(0x228), 195 }, 196 /* 197 * Instance 3, 198 */ 199 { 200 { 201 { 202 /* crb_rcv_producer_offset: */ 203 NETXEN_NIC_REG(0x22c), 204 /* crb_rcv_consumer_offset: */ 205 NETXEN_NIC_REG(0x230), 206 /* crb_gloablrcv_ring: */ 207 NETXEN_NIC_REG(0x234), 208 /* crb_rcv_ring_size */ 209 NETXEN_NIC_REG(0x238), 210 }, 211 /* Jumbo frames */ 212 { 213 /* crb_rcv_producer_offset: */ 214 NETXEN_NIC_REG(0x23c), 215 /* crb_rcv_consumer_offset: */ 216 NETXEN_NIC_REG(0x240), 217 /* crb_gloablrcv_ring: */ 218 NETXEN_NIC_REG(0x244), 219 /* crb_rcv_ring_size */ 220 NETXEN_NIC_REG(0x248), 221 }, 222 /* LRO */ 223 { 224 /* crb_rcv_producer_offset: */ 225 NETXEN_NIC_REG(0x24c), 226 /* crb_rcv_consumer_offset: */ 227 NETXEN_NIC_REG(0x250), 228 /* crb_gloablrcv_ring: */ 229 NETXEN_NIC_REG(0x254), 230 /* crb_rcv_ring_size */ 231 NETXEN_NIC_REG(0x258), 232 } 233 }, 234 /* crb_rcvstatus_ring: */ 235 NETXEN_NIC_REG(0x25c), 236 /* crb_rcv_status_producer: */ 237 NETXEN_NIC_REG(0x260), 238 /* crb_rcv_status_consumer: */ 239 NETXEN_NIC_REG(0x264), 240 /* crb_rcvpeg_state: */ 241 NETXEN_NIC_REG(0x268), 242 /* crb_status_ring_size */ 243 NETXEN_NIC_REG(0x26c), 244 }, 245}; 246 247u64 ctx_addr_sig_regs[][3] = { 248 {NETXEN_NIC_REG(0x188), NETXEN_NIC_REG(0x18c), NETXEN_NIC_REG(0x1c0)}, 249 {NETXEN_NIC_REG(0x190), NETXEN_NIC_REG(0x194), NETXEN_NIC_REG(0x1c4)}, 250 {NETXEN_NIC_REG(0x198), NETXEN_NIC_REG(0x19c), NETXEN_NIC_REG(0x1c8)}, 251 {NETXEN_NIC_REG(0x1a0), NETXEN_NIC_REG(0x1a4), NETXEN_NIC_REG(0x1cc)} 252}; 253 254 255/* PCI Windowing for DDR regions. */ 256 257#define ADDR_IN_RANGE(addr, low, high) \ 258 (((addr) <= (high)) && ((addr) >= (low))) 259 260#define NETXEN_FLASH_BASE (NETXEN_BOOTLD_START) 261#define NETXEN_PHANTOM_MEM_BASE (NETXEN_FLASH_BASE) 262#define NETXEN_MAX_MTU 8000 + NETXEN_ENET_HEADER_SIZE + NETXEN_ETH_FCS_SIZE 263#define NETXEN_MIN_MTU 64 264#define NETXEN_ETH_FCS_SIZE 4 265#define NETXEN_ENET_HEADER_SIZE 14 266#define NETXEN_WINDOW_ONE 0x2000000 /*CRB Window: bit 25 of CRB address */ 267#define NETXEN_FIRMWARE_LEN ((16 * 1024) / 4) 268#define NETXEN_NIU_HDRSIZE (0x1 << 6) 269#define NETXEN_NIU_TLRSIZE (0x1 << 5) 270 271#define lower32(x) ((u32)((x) & 0xffffffff)) 272#define upper32(x) \ 273 ((u32)(((unsigned long long)(x) >> 32) & 0xffffffff)) 274 275#define NETXEN_NIC_ZERO_PAUSE_ADDR 0ULL 276#define NETXEN_NIC_UNIT_PAUSE_ADDR 0x200ULL 277#define NETXEN_NIC_EPG_PAUSE_ADDR1 0x2200010000c28001ULL 278#define NETXEN_NIC_EPG_PAUSE_ADDR2 0x0100088866554433ULL 279 280#define NETXEN_NIC_WINDOW_MARGIN 0x100000 281 282unsigned long netxen_nic_pci_set_window(struct netxen_adapter *adapter, 283 unsigned long long addr); 284void netxen_free_hw_resources(struct netxen_adapter *adapter); 285 286int netxen_nic_set_mac(struct net_device *netdev, void *p) 287{ 288 struct netxen_adapter *adapter = netdev_priv(netdev); 289 struct sockaddr *addr = p; 290 291 if (netif_running(netdev)) 292 return -EBUSY; 293 294 if (!is_valid_ether_addr(addr->sa_data)) 295 return -EADDRNOTAVAIL; 296 297 DPRINTK(INFO, "valid ether addr\n"); 298 memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); 299 300 if (adapter->macaddr_set) 301 adapter->macaddr_set(adapter, addr->sa_data); 302 303 return 0; 304} 305 306/* 307 * netxen_nic_set_multi - Multicast 308 */ 309void netxen_nic_set_multi(struct net_device *netdev) 310{ 311 struct netxen_adapter *adapter = netdev_priv(netdev); 312 struct dev_mc_list *mc_ptr; 313 314 mc_ptr = netdev->mc_list; 315 if (netdev->flags & IFF_PROMISC) { 316 if (adapter->set_promisc) 317 adapter->set_promisc(adapter, 318 NETXEN_NIU_PROMISC_MODE); 319 } else { 320 if (adapter->unset_promisc) 321 adapter->unset_promisc(adapter, 322 NETXEN_NIU_NON_PROMISC_MODE); 323 } 324} 325 326/* 327 * netxen_nic_change_mtu - Change the Maximum Transfer Unit 328 * @returns 0 on success, negative on failure 329 */ 330int netxen_nic_change_mtu(struct net_device *netdev, int mtu) 331{ 332 struct netxen_adapter *adapter = netdev_priv(netdev); 333 int eff_mtu = mtu + NETXEN_ENET_HEADER_SIZE + NETXEN_ETH_FCS_SIZE; 334 335 if ((eff_mtu > NETXEN_MAX_MTU) || (eff_mtu < NETXEN_MIN_MTU)) { 336 printk(KERN_ERR "%s: %s %d is not supported.\n", 337 netxen_nic_driver_name, netdev->name, mtu); 338 return -EINVAL; 339 } 340 341 if (adapter->set_mtu) 342 adapter->set_mtu(adapter, mtu); 343 netdev->mtu = mtu; 344 345 return 0; 346} 347 348/* 349 * check if the firmware has been downloaded and ready to run and 350 * setup the address for the descriptors in the adapter 351 */ 352int netxen_nic_hw_resources(struct netxen_adapter *adapter) 353{ 354 struct netxen_hardware_context *hw = &adapter->ahw; 355 u32 state = 0; 356 void *addr; 357 int loops = 0, err = 0; 358 int ctx, ring; 359 struct netxen_recv_context *recv_ctx; 360 struct netxen_rcv_desc_ctx *rcv_desc; 361 int func_id = adapter->portnum; 362 363 DPRINTK(INFO, "crb_base: %lx %x", NETXEN_PCI_CRBSPACE, 364 PCI_OFFSET_SECOND_RANGE(adapter, NETXEN_PCI_CRBSPACE)); 365 DPRINTK(INFO, "cam base: %lx %x", NETXEN_CRB_CAM, 366 pci_base_offset(adapter, NETXEN_CRB_CAM)); 367 DPRINTK(INFO, "cam RAM: %lx %x", NETXEN_CAM_RAM_BASE, 368 pci_base_offset(adapter, NETXEN_CAM_RAM_BASE)); 369 370 371 for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { 372 DPRINTK(INFO, "Command Peg ready..waiting for rcv peg\n"); 373 loops = 0; 374 state = 0; 375 /* Window 1 call */ 376 state = readl(NETXEN_CRB_NORMALIZE(adapter, 377 recv_crb_registers[ctx]. 378 crb_rcvpeg_state)); 379 while (state != PHAN_PEG_RCV_INITIALIZED && loops < 20) { 380 msleep(1); 381 /* Window 1 call */ 382 state = readl(NETXEN_CRB_NORMALIZE(adapter, 383 recv_crb_registers 384 [ctx]. 385 crb_rcvpeg_state)); 386 loops++; 387 } 388 if (loops >= 20) { 389 printk(KERN_ERR "Rcv Peg initialization not complete:" 390 "%x.\n", state); 391 err = -EIO; 392 return err; 393 } 394 } 395 adapter->intr_scheme = readl( 396 NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_CAPABILITIES_FW)); 397 printk(KERN_NOTICE "%s: FW capabilities:0x%x\n", netxen_nic_driver_name, 398 adapter->intr_scheme); 399 DPRINTK(INFO, "Receive Peg ready too. starting stuff\n"); 400 401 addr = netxen_alloc(adapter->ahw.pdev, 402 sizeof(struct netxen_ring_ctx) + 403 sizeof(uint32_t), 404 (dma_addr_t *) & adapter->ctx_desc_phys_addr, 405 &adapter->ctx_desc_pdev); 406 407 printk(KERN_INFO "ctx_desc_phys_addr: 0x%llx\n", 408 (unsigned long long) adapter->ctx_desc_phys_addr); 409 if (addr == NULL) { 410 DPRINTK(ERR, "bad return from pci_alloc_consistent\n"); 411 err = -ENOMEM; 412 return err; 413 } 414 memset(addr, 0, sizeof(struct netxen_ring_ctx)); 415 adapter->ctx_desc = (struct netxen_ring_ctx *)addr; 416 adapter->ctx_desc->ctx_id = cpu_to_le32(adapter->portnum); 417 adapter->ctx_desc->cmd_consumer_offset = 418 cpu_to_le64(adapter->ctx_desc_phys_addr + 419 sizeof(struct netxen_ring_ctx)); 420 adapter->cmd_consumer = (uint32_t *) (((char *)addr) + 421 sizeof(struct netxen_ring_ctx)); 422 423 addr = netxen_alloc(adapter->ahw.pdev, 424 sizeof(struct cmd_desc_type0) * 425 adapter->max_tx_desc_count, 426 (dma_addr_t *) & hw->cmd_desc_phys_addr, 427 &adapter->ahw.cmd_desc_pdev); 428 printk(KERN_INFO "cmd_desc_phys_addr: 0x%llx\n", 429 (unsigned long long) hw->cmd_desc_phys_addr); 430 431 if (addr == NULL) { 432 DPRINTK(ERR, "bad return from pci_alloc_consistent\n"); 433 netxen_free_hw_resources(adapter); 434 return -ENOMEM; 435 } 436 437 adapter->ctx_desc->cmd_ring_addr = 438 cpu_to_le64(hw->cmd_desc_phys_addr); 439 adapter->ctx_desc->cmd_ring_size = 440 cpu_to_le32(adapter->max_tx_desc_count); 441 442 hw->cmd_desc_head = (struct cmd_desc_type0 *)addr; 443 444 for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { 445 recv_ctx = &adapter->recv_ctx[ctx]; 446 447 for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { 448 rcv_desc = &recv_ctx->rcv_desc[ring]; 449 addr = netxen_alloc(adapter->ahw.pdev, 450 RCV_DESC_RINGSIZE, 451 &rcv_desc->phys_addr, 452 &rcv_desc->phys_pdev); 453 if (addr == NULL) { 454 DPRINTK(ERR, "bad return from " 455 "pci_alloc_consistent\n"); 456 netxen_free_hw_resources(adapter); 457 err = -ENOMEM; 458 return err; 459 } 460 rcv_desc->desc_head = (struct rcv_desc *)addr; 461 adapter->ctx_desc->rcv_ctx[ring].rcv_ring_addr = 462 cpu_to_le64(rcv_desc->phys_addr); 463 adapter->ctx_desc->rcv_ctx[ring].rcv_ring_size = 464 cpu_to_le32(rcv_desc->max_rx_desc_count); 465 } 466 467 addr = netxen_alloc(adapter->ahw.pdev, STATUS_DESC_RINGSIZE, 468 &recv_ctx->rcv_status_desc_phys_addr, 469 &recv_ctx->rcv_status_desc_pdev); 470 if (addr == NULL) { 471 DPRINTK(ERR, "bad return from" 472 " pci_alloc_consistent\n"); 473 netxen_free_hw_resources(adapter); 474 err = -ENOMEM; 475 return err; 476 } 477 recv_ctx->rcv_status_desc_head = (struct status_desc *)addr; 478 adapter->ctx_desc->sts_ring_addr = 479 cpu_to_le64(recv_ctx->rcv_status_desc_phys_addr); 480 adapter->ctx_desc->sts_ring_size = 481 cpu_to_le32(adapter->max_rx_desc_count); 482 483 } 484 /* Window = 1 */ 485 486 writel(lower32(adapter->ctx_desc_phys_addr), 487 NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_ADDR_REG_LO(func_id))); 488 writel(upper32(adapter->ctx_desc_phys_addr), 489 NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_ADDR_REG_HI(func_id))); 490 writel(NETXEN_CTX_SIGNATURE | func_id, 491 NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_SIGNATURE_REG(func_id))); 492 return err; 493} 494 495void netxen_free_hw_resources(struct netxen_adapter *adapter) 496{ 497 struct netxen_recv_context *recv_ctx; 498 struct netxen_rcv_desc_ctx *rcv_desc; 499 int ctx, ring; 500 501 if (adapter->ctx_desc != NULL) { 502 pci_free_consistent(adapter->ctx_desc_pdev, 503 sizeof(struct netxen_ring_ctx) + 504 sizeof(uint32_t), 505 adapter->ctx_desc, 506 adapter->ctx_desc_phys_addr); 507 adapter->ctx_desc = NULL; 508 } 509 510 if (adapter->ahw.cmd_desc_head != NULL) { 511 pci_free_consistent(adapter->ahw.cmd_desc_pdev, 512 sizeof(struct cmd_desc_type0) * 513 adapter->max_tx_desc_count, 514 adapter->ahw.cmd_desc_head, 515 adapter->ahw.cmd_desc_phys_addr); 516 adapter->ahw.cmd_desc_head = NULL; 517 } 518 519 for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { 520 recv_ctx = &adapter->recv_ctx[ctx]; 521 for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { 522 rcv_desc = &recv_ctx->rcv_desc[ring]; 523 524 if (rcv_desc->desc_head != NULL) { 525 pci_free_consistent(rcv_desc->phys_pdev, 526 RCV_DESC_RINGSIZE, 527 rcv_desc->desc_head, 528 rcv_desc->phys_addr); 529 rcv_desc->desc_head = NULL; 530 } 531 } 532 533 if (recv_ctx->rcv_status_desc_head != NULL) { 534 pci_free_consistent(recv_ctx->rcv_status_desc_pdev, 535 STATUS_DESC_RINGSIZE, 536 recv_ctx->rcv_status_desc_head, 537 recv_ctx-> 538 rcv_status_desc_phys_addr); 539 recv_ctx->rcv_status_desc_head = NULL; 540 } 541 } 542} 543 544void netxen_tso_check(struct netxen_adapter *adapter, 545 struct cmd_desc_type0 *desc, struct sk_buff *skb) 546{ 547 if (desc->mss) { 548 desc->total_hdr_length = (sizeof(struct ethhdr) + 549 ip_hdrlen(skb) + tcp_hdrlen(skb)); 550 netxen_set_cmd_desc_opcode(desc, TX_TCP_LSO); 551 } else if (skb->ip_summed == CHECKSUM_PARTIAL) { 552 if (ip_hdr(skb)->protocol == IPPROTO_TCP) { 553 netxen_set_cmd_desc_opcode(desc, TX_TCP_PKT); 554 } else if (ip_hdr(skb)->protocol == IPPROTO_UDP) { 555 netxen_set_cmd_desc_opcode(desc, TX_UDP_PKT); 556 } else { 557 return; 558 } 559 } 560 desc->tcp_hdr_offset = skb_transport_offset(skb); 561 desc->ip_hdr_offset = skb_network_offset(skb); 562} 563 564int netxen_is_flash_supported(struct netxen_adapter *adapter) 565{ 566 const int locs[] = { 0, 0x4, 0x100, 0x4000, 0x4128 }; 567 int addr, val01, val02, i, j; 568 569 /* if the flash size less than 4Mb, make huge war cry and die */ 570 for (j = 1; j < 4; j++) { 571 addr = j * NETXEN_NIC_WINDOW_MARGIN; 572 for (i = 0; i < (sizeof(locs) / sizeof(locs[0])); i++) { 573 if (netxen_rom_fast_read(adapter, locs[i], &val01) == 0 574 && netxen_rom_fast_read(adapter, (addr + locs[i]), 575 &val02) == 0) { 576 if (val01 == val02) 577 return -1; 578 } else 579 return -1; 580 } 581 } 582 583 return 0; 584} 585 586static int netxen_get_flash_block(struct netxen_adapter *adapter, int base, 587 int size, u32 * buf) 588{ 589 int i, addr; 590 u32 *ptr32; 591 592 addr = base; 593 ptr32 = buf; 594 for (i = 0; i < size / sizeof(u32); i++) { 595 if (netxen_rom_fast_read(adapter, addr, ptr32) == -1) 596 return -1; 597 *ptr32 = cpu_to_le32(*ptr32); 598 ptr32++; 599 addr += sizeof(u32); 600 } 601 if ((char *)buf + size > (char *)ptr32) { 602 u32 local; 603 604 if (netxen_rom_fast_read(adapter, addr, &local) == -1) 605 return -1; 606 local = cpu_to_le32(local); 607 memcpy(ptr32, &local, (char *)buf + size - (char *)ptr32); 608 } 609 610 return 0; 611} 612 613int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, u64 mac[]) 614{ 615 u32 *pmac = (u32 *) & mac[0]; 616 617 if (netxen_get_flash_block(adapter, 618 NETXEN_USER_START + 619 offsetof(struct netxen_new_user_info, 620 mac_addr), 621 FLASH_NUM_PORTS * sizeof(u64), pmac) == -1) { 622 return -1; 623 } 624 if (*mac == ~0ULL) { 625 if (netxen_get_flash_block(adapter, 626 NETXEN_USER_START_OLD + 627 offsetof(struct netxen_user_old_info, 628 mac_addr), 629 FLASH_NUM_PORTS * sizeof(u64), 630 pmac) == -1) 631 return -1; 632 if (*mac == ~0ULL) 633 return -1; 634 } 635 return 0; 636} 637 638/* 639 * Changes the CRB window to the specified window. 640 */ 641void netxen_nic_pci_change_crbwindow(struct netxen_adapter *adapter, u32 wndw) 642{ 643 void __iomem *offset; 644 u32 tmp; 645 int count = 0; 646 647 if (adapter->curr_window == wndw) 648 return; 649 switch(adapter->ahw.pci_func) { 650 case 0: 651 offset = PCI_OFFSET_SECOND_RANGE(adapter, 652 NETXEN_PCIX_PH_REG(PCIX_CRB_WINDOW)); 653 break; 654 case 1: 655 offset = PCI_OFFSET_SECOND_RANGE(adapter, 656 NETXEN_PCIX_PH_REG(PCIX_CRB_WINDOW_F1)); 657 break; 658 case 2: 659 offset = PCI_OFFSET_SECOND_RANGE(adapter, 660 NETXEN_PCIX_PH_REG(PCIX_CRB_WINDOW_F2)); 661 break; 662 case 3: 663 offset = PCI_OFFSET_SECOND_RANGE(adapter, 664 NETXEN_PCIX_PH_REG(PCIX_CRB_WINDOW_F3)); 665 break; 666 default: 667 printk(KERN_INFO "Changing the window for PCI function" 668 "%d\n", adapter->ahw.pci_func); 669 offset = PCI_OFFSET_SECOND_RANGE(adapter, 670 NETXEN_PCIX_PH_REG(PCIX_CRB_WINDOW)); 671 break; 672 } 673 /* 674 * Move the CRB window. 675 * We need to write to the "direct access" region of PCI 676 * to avoid a race condition where the window register has 677 * not been successfully written across CRB before the target 678 * register address is received by PCI. The direct region bypasses 679 * the CRB bus. 680 */ 681 682 if (wndw & 0x1) 683 wndw = NETXEN_WINDOW_ONE; 684 685 writel(wndw, offset); 686 687 /* MUST make sure window is set before we forge on... */ 688 while ((tmp = readl(offset)) != wndw) { 689 printk(KERN_WARNING "%s: %s WARNING: CRB window value not " 690 "registered properly: 0x%08x.\n", 691 netxen_nic_driver_name, __FUNCTION__, tmp); 692 mdelay(1); 693 if (count >= 10) 694 break; 695 count++; 696 } 697 698 if (wndw == NETXEN_WINDOW_ONE) 699 adapter->curr_window = 1; 700 else 701 adapter->curr_window = 0; 702} 703 704int netxen_load_firmware(struct netxen_adapter *adapter) 705{ 706 int i; 707 u32 data, size = 0; 708 u32 flashaddr = NETXEN_FLASH_BASE, memaddr = NETXEN_PHANTOM_MEM_BASE; 709 u64 off; 710 void __iomem *addr; 711 712 size = NETXEN_FIRMWARE_LEN; 713 writel(1, NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CAS_RST)); 714 715 for (i = 0; i < size; i++) { 716 int retries = 10; 717 if (netxen_rom_fast_read(adapter, flashaddr, (int *)&data) != 0) 718 return -EIO; 719 720 off = netxen_nic_pci_set_window(adapter, memaddr); 721 addr = pci_base_offset(adapter, off); 722 writel(data, addr); 723 do { 724 if (readl(addr) == data) 725 break; 726 msleep(100); 727 writel(data, addr); 728 } while (--retries); 729 if (!retries) { 730 printk(KERN_ERR "%s: firmware load aborted, write failed at 0x%x\n", 731 netxen_nic_driver_name, memaddr); 732 return -EIO; 733 } 734 flashaddr += 4; 735 memaddr += 4; 736 } 737 udelay(100); 738 /* make sure Casper is powered on */ 739 writel(0x3fff, 740 NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL)); 741 writel(0, NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CAS_RST)); 742 743 return 0; 744} 745 746int 747netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off, void *data, 748 int len) 749{ 750 void __iomem *addr; 751 752 if (ADDR_IN_WINDOW1(off)) { 753 addr = NETXEN_CRB_NORMALIZE(adapter, off); 754 } else { /* Window 0 */ 755 addr = pci_base_offset(adapter, off); 756 netxen_nic_pci_change_crbwindow(adapter, 0); 757 } 758 759 DPRINTK(INFO, "writing to base %lx offset %llx addr %p" 760 " data %llx len %d\n", 761 pci_base(adapter, off), off, addr, 762 *(unsigned long long *)data, len); 763 if (!addr) { 764 netxen_nic_pci_change_crbwindow(adapter, 1); 765 return 1; 766 } 767 768 switch (len) { 769 case 1: 770 writeb(*(u8 *) data, addr); 771 break; 772 case 2: 773 writew(*(u16 *) data, addr); 774 break; 775 case 4: 776 writel(*(u32 *) data, addr); 777 break; 778 case 8: 779 writeq(*(u64 *) data, addr); 780 break; 781 default: 782 DPRINTK(INFO, 783 "writing data %lx to offset %llx, num words=%d\n", 784 *(unsigned long *)data, off, (len >> 3)); 785 786 netxen_nic_hw_block_write64((u64 __iomem *) data, addr, 787 (len >> 3)); 788 break; 789 } 790 if (!ADDR_IN_WINDOW1(off)) 791 netxen_nic_pci_change_crbwindow(adapter, 1); 792 793 return 0; 794} 795 796int 797netxen_nic_hw_read_wx(struct netxen_adapter *adapter, u64 off, void *data, 798 int len) 799{ 800 void __iomem *addr; 801 802 if (ADDR_IN_WINDOW1(off)) { /* Window 1 */ 803 addr = NETXEN_CRB_NORMALIZE(adapter, off); 804 } else { /* Window 0 */ 805 addr = pci_base_offset(adapter, off); 806 netxen_nic_pci_change_crbwindow(adapter, 0); 807 } 808 809 DPRINTK(INFO, "reading from base %lx offset %llx addr %p\n", 810 pci_base(adapter, off), off, addr); 811 if (!addr) { 812 netxen_nic_pci_change_crbwindow(adapter, 1); 813 return 1; 814 } 815 switch (len) { 816 case 1: 817 *(u8 *) data = readb(addr); 818 break; 819 case 2: 820 *(u16 *) data = readw(addr); 821 break; 822 case 4: 823 *(u32 *) data = readl(addr); 824 break; 825 case 8: 826 *(u64 *) data = readq(addr); 827 break; 828 default: 829 netxen_nic_hw_block_read64((u64 __iomem *) data, addr, 830 (len >> 3)); 831 break; 832 } 833 DPRINTK(INFO, "read %lx\n", *(unsigned long *)data); 834 835 if (!ADDR_IN_WINDOW1(off)) 836 netxen_nic_pci_change_crbwindow(adapter, 1); 837 838 return 0; 839} 840 841void netxen_nic_reg_write(struct netxen_adapter *adapter, u64 off, u32 val) 842{ /* Only for window 1 */ 843 void __iomem *addr; 844 845 addr = NETXEN_CRB_NORMALIZE(adapter, off); 846 DPRINTK(INFO, "writing to base %lx offset %llx addr %p data %x\n", 847 pci_base(adapter, off), off, addr, val); 848 writel(val, addr); 849 850} 851 852int netxen_nic_reg_read(struct netxen_adapter *adapter, u64 off) 853{ /* Only for window 1 */ 854 void __iomem *addr; 855 int val; 856 857 addr = NETXEN_CRB_NORMALIZE(adapter, off); 858 DPRINTK(INFO, "reading from base %lx offset %llx addr %p\n", 859 pci_base(adapter, off), off, addr); 860 val = readl(addr); 861 writel(val, addr); 862 863 return val; 864} 865 866/* Change the window to 0, write and change back to window 1. */ 867void netxen_nic_write_w0(struct netxen_adapter *adapter, u32 index, u32 value) 868{ 869 void __iomem *addr; 870 871 netxen_nic_pci_change_crbwindow(adapter, 0); 872 addr = pci_base_offset(adapter, index); 873 writel(value, addr); 874 netxen_nic_pci_change_crbwindow(adapter, 1); 875} 876 877/* Change the window to 0, read and change back to window 1. */ 878void netxen_nic_read_w0(struct netxen_adapter *adapter, u32 index, u32 * value) 879{ 880 void __iomem *addr; 881 882 addr = pci_base_offset(adapter, index); 883 884 netxen_nic_pci_change_crbwindow(adapter, 0); 885 *value = readl(addr); 886 netxen_nic_pci_change_crbwindow(adapter, 1); 887} 888 889int netxen_pci_set_window_warning_count = 0; 890 891unsigned long 892netxen_nic_pci_set_window(struct netxen_adapter *adapter, 893 unsigned long long addr) 894{ 895 static int ddr_mn_window = -1; 896 static int qdr_sn_window = -1; 897 int window; 898 899 if (ADDR_IN_RANGE(addr, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) { 900 /* DDR network side */ 901 addr -= NETXEN_ADDR_DDR_NET; 902 window = (addr >> 25) & 0x3ff; 903 if (ddr_mn_window != window) { 904 ddr_mn_window = window; 905 writel(window, PCI_OFFSET_SECOND_RANGE(adapter, 906 NETXEN_PCIX_PH_REG 907 (PCIX_MN_WINDOW))); 908 /* MUST make sure window is set before we forge on... */ 909 readl(PCI_OFFSET_SECOND_RANGE(adapter, 910 NETXEN_PCIX_PH_REG 911 (PCIX_MN_WINDOW))); 912 } 913 addr -= (window * NETXEN_WINDOW_ONE); 914 addr += NETXEN_PCI_DDR_NET; 915 } else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) { 916 addr -= NETXEN_ADDR_OCM0; 917 addr += NETXEN_PCI_OCM0; 918 } else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) { 919 addr -= NETXEN_ADDR_OCM1; 920 addr += NETXEN_PCI_OCM1; 921 } else 922 if (ADDR_IN_RANGE 923 (addr, NETXEN_ADDR_QDR_NET, NETXEN_ADDR_QDR_NET_MAX)) { 924 /* QDR network side */ 925 addr -= NETXEN_ADDR_QDR_NET; 926 window = (addr >> 22) & 0x3f; 927 if (qdr_sn_window != window) { 928 qdr_sn_window = window; 929 writel((window << 22), 930 PCI_OFFSET_SECOND_RANGE(adapter, 931 NETXEN_PCIX_PH_REG 932 (PCIX_SN_WINDOW))); 933 /* MUST make sure window is set before we forge on... */ 934 readl(PCI_OFFSET_SECOND_RANGE(adapter, 935 NETXEN_PCIX_PH_REG 936 (PCIX_SN_WINDOW))); 937 } 938 addr -= (window * 0x400000); 939 addr += NETXEN_PCI_QDR_NET; 940 } else { 941 /* 942 * peg gdb frequently accesses memory that doesn't exist, 943 * this limits the chit chat so debugging isn't slowed down. 944 */ 945 if ((netxen_pci_set_window_warning_count++ < 8) 946 || (netxen_pci_set_window_warning_count % 64 == 0)) 947 printk("%s: Warning:netxen_nic_pci_set_window()" 948 " Unknown address range!\n", 949 netxen_nic_driver_name); 950 951 } 952 return addr; 953} 954 955int 956netxen_nic_erase_pxe(struct netxen_adapter *adapter) 957{ 958 if (netxen_rom_fast_write(adapter, NETXEN_PXE_START, 0) == -1) { 959 printk(KERN_ERR "%s: erase pxe failed\n", 960 netxen_nic_driver_name); 961 return -1; 962 } 963 return 0; 964} 965 966int netxen_nic_get_board_info(struct netxen_adapter *adapter) 967{ 968 int rv = 0; 969 int addr = NETXEN_BRDCFG_START; 970 struct netxen_board_info *boardinfo; 971 int index; 972 u32 *ptr32; 973 974 boardinfo = &adapter->ahw.boardcfg; 975 ptr32 = (u32 *) boardinfo; 976 977 for (index = 0; index < sizeof(struct netxen_board_info) / sizeof(u32); 978 index++) { 979 if (netxen_rom_fast_read(adapter, addr, ptr32) == -1) { 980 return -EIO; 981 } 982 ptr32++; 983 addr += sizeof(u32); 984 } 985 if (boardinfo->magic != NETXEN_BDINFO_MAGIC) { 986 printk("%s: ERROR reading %s board config." 987 " Read %x, expected %x\n", netxen_nic_driver_name, 988 netxen_nic_driver_name, 989 boardinfo->magic, NETXEN_BDINFO_MAGIC); 990 rv = -1; 991 } 992 if (boardinfo->header_version != NETXEN_BDINFO_VERSION) { 993 printk("%s: Unknown board config version." 994 " Read %x, expected %x\n", netxen_nic_driver_name, 995 boardinfo->header_version, NETXEN_BDINFO_VERSION); 996 rv = -1; 997 } 998 999 DPRINTK(INFO, "Discovered board type:0x%x ", boardinfo->board_type); 1000 switch ((netxen_brdtype_t) boardinfo->board_type) { 1001 case NETXEN_BRDTYPE_P2_SB35_4G: 1002 adapter->ahw.board_type = NETXEN_NIC_GBE; 1003 break; 1004 case NETXEN_BRDTYPE_P2_SB31_10G: 1005 case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ: 1006 case NETXEN_BRDTYPE_P2_SB31_10G_HMEZ: 1007 case NETXEN_BRDTYPE_P2_SB31_10G_CX4: 1008 adapter->ahw.board_type = NETXEN_NIC_XGBE; 1009 break; 1010 case NETXEN_BRDTYPE_P1_BD: 1011 case NETXEN_BRDTYPE_P1_SB: 1012 case NETXEN_BRDTYPE_P1_SMAX: 1013 case NETXEN_BRDTYPE_P1_SOCK: 1014 adapter->ahw.board_type = NETXEN_NIC_GBE; 1015 break; 1016 default: 1017 printk("%s: Unknown(%x)\n", netxen_nic_driver_name, 1018 boardinfo->board_type); 1019 break; 1020 } 1021 1022 return rv; 1023} 1024 1025/* NIU access sections */ 1026 1027int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu) 1028{ 1029 netxen_nic_write_w0(adapter, 1030 NETXEN_NIU_GB_MAX_FRAME_SIZE( 1031 physical_port[adapter->portnum]), new_mtu); 1032 return 0; 1033} 1034 1035int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu) 1036{ 1037 new_mtu += NETXEN_NIU_HDRSIZE + NETXEN_NIU_TLRSIZE; 1038 if (physical_port[adapter->portnum] == 0) 1039 netxen_nic_write_w0(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE, 1040 new_mtu); 1041 else 1042 netxen_nic_write_w0(adapter, NETXEN_NIU_XG1_MAX_FRAME_SIZE, 1043 new_mtu); 1044 return 0; 1045} 1046 1047void netxen_nic_init_niu_gb(struct netxen_adapter *adapter) 1048{ 1049 netxen_niu_gbe_init_port(adapter, physical_port[adapter->portnum]); 1050} 1051 1052void 1053netxen_crb_writelit_adapter(struct netxen_adapter *adapter, unsigned long off, 1054 int data) 1055{ 1056 void __iomem *addr; 1057 1058 if (ADDR_IN_WINDOW1(off)) { 1059 writel(data, NETXEN_CRB_NORMALIZE(adapter, off)); 1060 } else { 1061 netxen_nic_pci_change_crbwindow(adapter, 0); 1062 addr = pci_base_offset(adapter, off); 1063 writel(data, addr); 1064 netxen_nic_pci_change_crbwindow(adapter, 1); 1065 } 1066} 1067 1068void netxen_nic_set_link_parameters(struct netxen_adapter *adapter) 1069{ 1070 __u32 status; 1071 __u32 autoneg; 1072 __u32 mode; 1073 1074 netxen_nic_read_w0(adapter, NETXEN_NIU_MODE, &mode); 1075 if (netxen_get_niu_enable_ge(mode)) { /* Gb 10/100/1000 Mbps mode */ 1076 if (adapter->phy_read 1077 && adapter-> 1078 phy_read(adapter, 1079 NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, 1080 &status) == 0) { 1081 if (netxen_get_phy_link(status)) { 1082 switch (netxen_get_phy_speed(status)) { 1083 case 0: 1084 adapter->link_speed = SPEED_10; 1085 break; 1086 case 1: 1087 adapter->link_speed = SPEED_100; 1088 break; 1089 case 2: 1090 adapter->link_speed = SPEED_1000; 1091 break; 1092 default: 1093 adapter->link_speed = -1; 1094 break; 1095 } 1096 switch (netxen_get_phy_duplex(status)) { 1097 case 0: 1098 adapter->link_duplex = DUPLEX_HALF; 1099 break; 1100 case 1: 1101 adapter->link_duplex = DUPLEX_FULL; 1102 break; 1103 default: 1104 adapter->link_duplex = -1; 1105 break; 1106 } 1107 if (adapter->phy_read 1108 && adapter-> 1109 phy_read(adapter, 1110 NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG, 1111 &autoneg) != 0) 1112 adapter->link_autoneg = autoneg; 1113 } else 1114 goto link_down; 1115 } else { 1116 link_down: 1117 adapter->link_speed = -1; 1118 adapter->link_duplex = -1; 1119 } 1120 } 1121} 1122 1123void netxen_nic_flash_print(struct netxen_adapter *adapter) 1124{ 1125 int valid = 1; 1126 u32 fw_major = 0; 1127 u32 fw_minor = 0; 1128 u32 fw_build = 0; 1129 char brd_name[NETXEN_MAX_SHORT_NAME]; 1130 struct netxen_new_user_info user_info; 1131 int i, addr = NETXEN_USER_START; 1132 __le32 *ptr32; 1133 1134 struct netxen_board_info *board_info = &(adapter->ahw.boardcfg); 1135 if (board_info->magic != NETXEN_BDINFO_MAGIC) { 1136 printk 1137 ("NetXen Unknown board config, Read 0x%x expected as 0x%x\n", 1138 board_info->magic, NETXEN_BDINFO_MAGIC); 1139 valid = 0; 1140 } 1141 if (board_info->header_version != NETXEN_BDINFO_VERSION) { 1142 printk("NetXen Unknown board config version." 1143 " Read %x, expected %x\n", 1144 board_info->header_version, NETXEN_BDINFO_VERSION); 1145 valid = 0; 1146 } 1147 if (valid) { 1148 ptr32 = (u32 *) & user_info; 1149 for (i = 0; 1150 i < sizeof(struct netxen_new_user_info) / sizeof(u32); 1151 i++) { 1152 if (netxen_rom_fast_read(adapter, addr, ptr32) == -1) { 1153 printk("%s: ERROR reading %s board userarea.\n", 1154 netxen_nic_driver_name, 1155 netxen_nic_driver_name); 1156 return; 1157 } 1158 ptr32++; 1159 addr += sizeof(u32); 1160 } 1161 get_brd_name_by_type(board_info->board_type, brd_name); 1162 1163 printk("NetXen %s Board S/N %s Chip id 0x%x\n", 1164 brd_name, user_info.serial_num, board_info->chip_id); 1165 1166 printk("NetXen %s Board #%d, Chip id 0x%x\n", 1167 board_info->board_type == 0x0b ? "XGB" : "GBE", 1168 board_info->board_num, board_info->chip_id); 1169 fw_major = readl(NETXEN_CRB_NORMALIZE(adapter, 1170 NETXEN_FW_VERSION_MAJOR)); 1171 fw_minor = readl(NETXEN_CRB_NORMALIZE(adapter, 1172 NETXEN_FW_VERSION_MINOR)); 1173 fw_build = 1174 readl(NETXEN_CRB_NORMALIZE(adapter, NETXEN_FW_VERSION_SUB)); 1175 1176 printk("NetXen Firmware version %d.%d.%d\n", fw_major, fw_minor, 1177 fw_build); 1178 } 1179 if (fw_major != _NETXEN_NIC_LINUX_MAJOR) { 1180 printk(KERN_ERR "The mismatch in driver version and firmware " 1181 "version major number\n" 1182 "Driver version major number = %d \t" 1183 "Firmware version major number = %d \n", 1184 _NETXEN_NIC_LINUX_MAJOR, fw_major); 1185 adapter->driver_mismatch = 1; 1186 } 1187 if (fw_minor != _NETXEN_NIC_LINUX_MINOR && 1188 fw_minor != (_NETXEN_NIC_LINUX_MINOR + 1)) { 1189 printk(KERN_ERR "The mismatch in driver version and firmware " 1190 "version minor number\n" 1191 "Driver version minor number = %d \t" 1192 "Firmware version minor number = %d \n", 1193 _NETXEN_NIC_LINUX_MINOR, fw_minor); 1194 adapter->driver_mismatch = 1; 1195 } 1196 if (adapter->driver_mismatch) 1197 printk(KERN_INFO "Use the driver with version no %d.%d.xxx\n", 1198 fw_major, fw_minor); 1199} 1200