Merge ../linux-2.6-watchdog-mm
[pandora-kernel.git] / drivers / net / netxen / netxen_nic_hw.c
index 105c24f..f263232 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2003 - 2006 NetXen, Inc.
  * All rights reserved.
- * 
+ *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
  * MA  02111-1307, USA.
- * 
+ *
  * The full GNU General Public License is included in this distribution
  * in the file called LICENSE.
- * 
+ *
  * Contact Information:
  *    info@netxen.com
  * NetXen,
@@ -42,7 +42,7 @@
 
 #define NETXEN_FLASH_BASE      (BOOTLD_START)
 #define NETXEN_PHANTOM_MEM_BASE        (NETXEN_FLASH_BASE)
-#define NETXEN_MAX_MTU         8000
+#define NETXEN_MAX_MTU         8000 + NETXEN_ENET_HEADER_SIZE + NETXEN_ETH_FCS_SIZE
 #define NETXEN_MIN_MTU         64
 #define NETXEN_ETH_FCS_SIZE     4
 #define NETXEN_ENET_HEADER_SIZE 14
@@ -81,8 +81,8 @@ int netxen_nic_set_mac(struct net_device *netdev, void *p)
        DPRINTK(INFO, "valid ether addr\n");
        memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
 
-       if (adapter->ops->macaddr_set)
-               adapter->ops->macaddr_set(port, addr->sa_data);
+       if (adapter->macaddr_set)
+               adapter->macaddr_set(port, addr->sa_data);
 
        return 0;
 }
@@ -95,21 +95,21 @@ void netxen_nic_set_multi(struct net_device *netdev)
        struct netxen_port *port = netdev_priv(netdev);
        struct netxen_adapter *adapter = port->adapter;
        struct dev_mc_list *mc_ptr;
-       __le32 netxen_mac_addr_cntl_data = 0;
+       __u32 netxen_mac_addr_cntl_data = 0;
 
        mc_ptr = netdev->mc_list;
        if (netdev->flags & IFF_PROMISC) {
-               if (adapter->ops->set_promisc)
-                       adapter->ops->set_promisc(adapter,
-                                                 port->portnum,
-                                                 NETXEN_NIU_PROMISC_MODE);
+               if (adapter->set_promisc)
+                       adapter->set_promisc(adapter,
+                                            port->portnum,
+                                            NETXEN_NIU_PROMISC_MODE);
        } else {
-               if (adapter->ops->unset_promisc &&
+               if (adapter->unset_promisc &&
                    adapter->ahw.boardcfg.board_type
                    != NETXEN_BRDTYPE_P2_SB31_10G_IMEZ)
-                       adapter->ops->unset_promisc(adapter,
-                                                   port->portnum,
-                                                   NETXEN_NIU_NON_PROMISC_MODE);
+                       adapter->unset_promisc(adapter,
+                                              port->portnum,
+                                              NETXEN_NIU_NON_PROMISC_MODE);
        }
        if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
                netxen_nic_mcr_set_mode_select(netxen_mac_addr_cntl_data, 0x03);
@@ -160,8 +160,8 @@ int netxen_nic_change_mtu(struct net_device *netdev, int mtu)
                return -EINVAL;
        }
 
-       if (adapter->ops->set_mtu)
-               adapter->ops->set_mtu(port, mtu);
+       if (adapter->set_mtu)
+               adapter->set_mtu(port, mtu);
        netdev->mtu = mtu;
 
        return 0;
@@ -176,22 +176,18 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter)
        struct netxen_hardware_context *hw = &adapter->ahw;
        u32 state = 0;
        void *addr;
-       void *pause_addr;
        int loops = 0, err = 0;
        int ctx, ring;
        u32 card_cmdring = 0;
-       struct netxen_rcv_desc_crb *rcv_desc_crb = NULL;
        struct netxen_recv_context *recv_ctx;
        struct netxen_rcv_desc_ctx *rcv_desc;
 
-       DPRINTK(INFO, "crb_base: %lx %lx", NETXEN_PCI_CRBSPACE,
+       DPRINTK(INFO, "crb_base: %lx %x", NETXEN_PCI_CRBSPACE,
                PCI_OFFSET_SECOND_RANGE(adapter, NETXEN_PCI_CRBSPACE));
-       DPRINTK(INFO, "cam base: %lx %lx", NETXEN_CRB_CAM,
+       DPRINTK(INFO, "cam base: %lx %x", NETXEN_CRB_CAM,
                pci_base_offset(adapter, NETXEN_CRB_CAM));
-       DPRINTK(INFO, "cam RAM: %lx %lx", NETXEN_CAM_RAM_BASE,
+       DPRINTK(INFO, "cam RAM: %lx %x", NETXEN_CAM_RAM_BASE,
                pci_base_offset(adapter, NETXEN_CAM_RAM_BASE));
-       DPRINTK(INFO, "NIC base:%lx %lx\n", NIC_CRB_BASE_PORT1,
-               pci_base_offset(adapter, NIC_CRB_BASE_PORT1));
 
        /* Window 1 call */
        card_cmdring = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_CMDRING));
@@ -226,33 +222,42 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter)
        DPRINTK(INFO, "Recieve Peg ready too. starting stuff\n");
 
        addr = netxen_alloc(adapter->ahw.pdev,
-                           sizeof(struct cmd_desc_type0) *
-                           adapter->max_tx_desc_count,
-                           &hw->cmd_desc_phys_addr, &hw->cmd_desc_pdev);
+                           sizeof(struct netxen_ring_ctx) +
+                           sizeof(uint32_t),
+                           (dma_addr_t *) & adapter->ctx_desc_phys_addr,
+                           &adapter->ctx_desc_pdev);
 
+       printk("ctx_desc_phys_addr: 0x%llx\n",
+              (u64) adapter->ctx_desc_phys_addr);
        if (addr == NULL) {
                DPRINTK(ERR, "bad return from pci_alloc_consistent\n");
-               return -ENOMEM;
-       }
+               err = -ENOMEM;
+               return err;
+       }
+       memset(addr, 0, sizeof(struct netxen_ring_ctx));
+       adapter->ctx_desc = (struct netxen_ring_ctx *)addr;
+       adapter->ctx_desc->cmd_consumer_offset =
+           cpu_to_le64(adapter->ctx_desc_phys_addr +
+                       sizeof(struct netxen_ring_ctx));
+       adapter->cmd_consumer = (uint32_t *) (((char *)addr) +
+                                             sizeof(struct netxen_ring_ctx));
+
+       addr = pci_alloc_consistent(adapter->ahw.pdev,
+                                   sizeof(struct cmd_desc_type0) *
+                                   adapter->max_tx_desc_count,
+                                   (dma_addr_t *) & hw->cmd_desc_phys_addr);
+       printk("cmd_desc_phys_addr: 0x%llx\n", (u64) hw->cmd_desc_phys_addr);
 
-       pause_addr = netxen_alloc(adapter->ahw.pdev, 512,
-                                 (dma_addr_t *) & hw->pause_physaddr,
-                                 &hw->pause_pdev);
-       if (pause_addr == NULL) {
-               DPRINTK(1, ERR, "bad return from pci_alloc_consistent\n");
+       if (addr == NULL) {
+               DPRINTK(ERR, "bad return from pci_alloc_consistent\n");
+               netxen_free_hw_resources(adapter);
                return -ENOMEM;
        }
 
-       hw->pauseaddr = (char *)pause_addr;
-       {
-               u64 *ptr = (u64 *) pause_addr;
-               *ptr++ = NETXEN_NIC_ZERO_PAUSE_ADDR;
-               *ptr++ = NETXEN_NIC_ZERO_PAUSE_ADDR;
-               *ptr++ = NETXEN_NIC_UNIT_PAUSE_ADDR;
-               *ptr++ = NETXEN_NIC_ZERO_PAUSE_ADDR;
-               *ptr++ = NETXEN_NIC_EPG_PAUSE_ADDR1;
-               *ptr++ = NETXEN_NIC_EPG_PAUSE_ADDR2;
-       }
+       adapter->ctx_desc->cmd_ring_addr =
+               cpu_to_le64(hw->cmd_desc_phys_addr);
+       adapter->ctx_desc->cmd_ring_size =
+               cpu_to_le32(adapter->max_tx_desc_count);
 
        hw->cmd_desc_head = (struct cmd_desc_type0 *)addr;
 
@@ -273,6 +278,10 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter)
                                return err;
                        }
                        rcv_desc->desc_head = (struct rcv_desc *)addr;
+                       adapter->ctx_desc->rcv_ctx[ring].rcv_ring_addr =
+                           cpu_to_le64(rcv_desc->phys_addr);
+                       adapter->ctx_desc->rcv_ctx[ring].rcv_ring_size =
+                           cpu_to_le32(rcv_desc->max_rx_desc_count);
                }
 
                addr = netxen_alloc(adapter->ahw.pdev, STATUS_DESC_RINGSIZE,
@@ -286,47 +295,20 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter)
                        return err;
                }
                recv_ctx->rcv_status_desc_head = (struct status_desc *)addr;
-               for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
-                       rcv_desc = &recv_ctx->rcv_desc[ring];
-                       rcv_desc_crb =
-                           &recv_crb_registers[ctx].rcv_desc_crb[ring];
-                       DPRINTK(INFO, "ring #%d crb global ring reg 0x%x\n",
-                               ring, rcv_desc_crb->crb_globalrcv_ring);
-                       /* Window = 1 */
-                       writel(lower32(rcv_desc->phys_addr),
-                              NETXEN_CRB_NORMALIZE(adapter,
-                                                   rcv_desc_crb->
-                                                   crb_globalrcv_ring));
-                       DPRINTK(INFO, "GLOBAL_RCV_RING ctx %d, addr 0x%x"
-                               " val 0x%llx,"
-                               " virt %p\n", ctx,
-                               rcv_desc_crb->crb_globalrcv_ring,
-                               (unsigned long long)rcv_desc->phys_addr,
-                               +rcv_desc->desc_head);
-               }
+               adapter->ctx_desc->sts_ring_addr =
+                   cpu_to_le64(recv_ctx->rcv_status_desc_phys_addr);
+               adapter->ctx_desc->sts_ring_size =
+                   cpu_to_le32(adapter->max_rx_desc_count);
 
-               /* Window = 1 */
-               writel(lower32(recv_ctx->rcv_status_desc_phys_addr),
-                      NETXEN_CRB_NORMALIZE(adapter,
-                                           recv_crb_registers[ctx].
-                                           crb_rcvstatus_ring));
-               DPRINTK(INFO, "RCVSTATUS_RING, ctx %d, addr 0x%x,"
-                       " val 0x%x,virt%p\n",
-                       ctx,
-                       recv_crb_registers[ctx].crb_rcvstatus_ring,
-                       (unsigned long long)recv_ctx->rcv_status_desc_phys_addr,
-                       recv_ctx->rcv_status_desc_head);
        }
        /* Window = 1 */
-       writel(lower32(hw->pause_physaddr),
-              NETXEN_CRB_NORMALIZE(adapter, CRB_PAUSE_ADDR_LO));
-       writel(upper32(hw->pause_physaddr),
-              NETXEN_CRB_NORMALIZE(adapter, CRB_PAUSE_ADDR_HI));
-
-       writel(lower32(hw->cmd_desc_phys_addr),
-              NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_CMD_ADDR_LO));
-       writel(upper32(hw->cmd_desc_phys_addr),
-              NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_CMD_ADDR_HI));
+
+       writel(lower32(adapter->ctx_desc_phys_addr),
+              NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_ADDR_REG_LO));
+       writel(upper32(adapter->ctx_desc_phys_addr),
+              NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_ADDR_REG_HI));
+       writel(NETXEN_CTX_SIGNATURE,
+              NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_SIGNATURE_REG));
        return err;
 }
 
@@ -336,6 +318,15 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter)
        struct netxen_rcv_desc_ctx *rcv_desc;
        int ctx, ring;
 
+       if (adapter->ctx_desc != NULL) {
+               pci_free_consistent(adapter->ctx_desc_pdev,
+                                   sizeof(struct netxen_ring_ctx) +
+                                   sizeof(uint32_t),
+                                   adapter->ctx_desc,
+                                   adapter->ctx_desc_phys_addr);
+               adapter->ctx_desc = NULL;
+       }
+
        if (adapter->ahw.cmd_desc_head != NULL) {
                pci_free_consistent(adapter->ahw.cmd_desc_pdev,
                                    sizeof(struct cmd_desc_type0) *
@@ -344,11 +335,9 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter)
                                    adapter->ahw.cmd_desc_phys_addr);
                adapter->ahw.cmd_desc_head = NULL;
        }
-       if (adapter->ahw.pauseaddr != NULL) {
-               pci_free_consistent(adapter->ahw.pause_pdev, 512,
-                                   adapter->ahw.pauseaddr,
-                                   adapter->ahw.pause_physaddr);
-               adapter->ahw.pauseaddr = NULL;
+       /* Special handling: there are 2 ports on this board */
+       if (adapter->ahw.boardcfg.board_type == NETXEN_BRDTYPE_P2_SB31_10G_IMEZ) {
+               adapter->ahw.max_ports = 2;
        }
 
        for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
@@ -383,19 +372,18 @@ void netxen_tso_check(struct netxen_adapter *adapter,
                desc->total_hdr_length = sizeof(struct ethhdr) +
                    ((skb->nh.iph)->ihl * sizeof(u32)) +
                    ((skb->h.th)->doff * sizeof(u32));
-               desc->opcode = TX_TCP_LSO;
-       } else if (skb->ip_summed == CHECKSUM_COMPLETE) {
+               netxen_set_cmd_desc_opcode(desc, TX_TCP_LSO);
+       } else if (skb->ip_summed == CHECKSUM_PARTIAL) {
                if (skb->nh.iph->protocol == IPPROTO_TCP) {
-                       desc->opcode = TX_TCP_PKT;
+                       netxen_set_cmd_desc_opcode(desc, TX_TCP_PKT);
                } else if (skb->nh.iph->protocol == IPPROTO_UDP) {
-                       desc->opcode = TX_UDP_PKT;
+                       netxen_set_cmd_desc_opcode(desc, TX_UDP_PKT);
                } else {
                        return;
                }
        }
        adapter->stats.xmitcsummed++;
-       CMD_DESC_TCP_HDR_OFFSET_WRT(desc, skb->h.raw - skb->data);
-       desc->length_tcp_hdr = cpu_to_le32(desc->length_tcp_hdr);
+       desc->tcp_hdr_offset = skb->h.raw - skb->data;
        desc->ip_hdr_offset = skb->nh.raw - skb->data;
 }
 
@@ -648,7 +636,7 @@ void netxen_nic_reg_write(struct netxen_adapter *adapter, u64 off, u32 val)
 
        addr = NETXEN_CRB_NORMALIZE(adapter, off);
        DPRINTK(INFO, "writing to base %lx offset %llx addr %p data %x\n",
-               pci_base(adapter, off), off, addr);
+               pci_base(adapter, off), off, addr, val);
        writel(val, addr);
 
 }
@@ -660,7 +648,7 @@ int netxen_nic_reg_read(struct netxen_adapter *adapter, u64 off)
 
        addr = NETXEN_CRB_NORMALIZE(adapter, off);
        DPRINTK(INFO, "reading from base %lx offset %llx addr %p\n",
-               adapter->ahw.pci_base, off, addr);
+               pci_base(adapter, off), off, addr);
        val = readl(addr);
        writel(val, addr);
 
@@ -848,8 +836,8 @@ void netxen_nic_stop_all_ports(struct netxen_adapter *adapter)
 
        for (port_nr = 0; port_nr < adapter->ahw.max_ports; port_nr++) {
                port = adapter->port[port_nr];
-               if (adapter->ops->stop_port)
-                       adapter->ops->stop_port(adapter, port->portnum);
+               if (adapter->stop_port)
+                       adapter->stop_port(adapter, port->portnum);
        }
 }
 
@@ -872,14 +860,14 @@ netxen_crb_writelit_adapter(struct netxen_adapter *adapter, unsigned long off,
 void netxen_nic_set_link_parameters(struct netxen_port *port)
 {
        struct netxen_adapter *adapter = port->adapter;
-       __le32 status;
-       u16 autoneg;
-       __le32 mode;
+       __u32 status;
+       __u32 autoneg;
+       __u32 mode;
 
        netxen_nic_read_w0(adapter, NETXEN_NIU_MODE, &mode);
        if (netxen_get_niu_enable_ge(mode)) {   /* Gb 10/100/1000 Mbps mode */
-               if (adapter->ops->phy_read
-                   && adapter->ops->
+               if (adapter->phy_read
+                   && adapter->
                    phy_read(adapter, port->portnum,
                             NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
                             &status) == 0) {
@@ -909,11 +897,11 @@ void netxen_nic_set_link_parameters(struct netxen_port *port)
                                        port->link_duplex = -1;
                                        break;
                                }
-                               if (adapter->ops->phy_read
-                                   && adapter->ops->
+                               if (adapter->phy_read
+                                   && adapter->
                                    phy_read(adapter, port->portnum,
                                             NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG,
-                                            (__le32 *) & autoneg) != 0)
+                                            &autoneg) != 0)
                                        port->link_autoneg = autoneg;
                        } else
                                goto link_down;
@@ -989,7 +977,8 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter)
                       _NETXEN_NIC_LINUX_MAJOR, fw_major);
                adapter->driver_mismatch = 1;
        }
-       if (fw_minor != _NETXEN_NIC_LINUX_MINOR) {
+       if (fw_minor != _NETXEN_NIC_LINUX_MINOR &&
+                       fw_minor != (_NETXEN_NIC_LINUX_MINOR + 1)) {
                printk(KERN_ERR "The mismatch in driver version and firmware "
                       "version minor number\n"
                       "Driver version minor number = %d \t"
@@ -1002,9 +991,3 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter)
                       fw_major, fw_minor);
 }
 
-int netxen_crb_read_val(struct netxen_adapter *adapter, unsigned long off)
-{
-       int data;
-       netxen_nic_hw_read_wx(adapter, off, &data, 4);
-       return data;
-}