net: replace uses of __constant_{endian}
[deliverable/linux.git] / drivers / net / netxen / netxen_nic_main.c
index cb39123818021a909dbf7d0ffe79566ead2a089c..ada462e94c96eadc6b85001fdf5dcaedcdf3e6c2 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/if_vlan.h>
 #include <net/ip.h>
+#include <linux/ipv6.h>
 
 MODULE_DESCRIPTION("NetXen Multi port (1/10) Gigabit Network Driver");
 MODULE_LICENSE("GPL");
@@ -243,7 +244,7 @@ static void netxen_check_options(struct netxen_adapter *adapter)
        case NETXEN_BRDTYPE_P3_4_GB:
        case NETXEN_BRDTYPE_P3_4_GB_MM:
                adapter->msix_supported = !!use_msi_x;
-               adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_10G;
+               adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G;
                break;
 
        case NETXEN_BRDTYPE_P2_SB35_4G:
@@ -252,6 +253,14 @@ static void netxen_check_options(struct netxen_adapter *adapter)
                adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G;
                break;
 
+       case NETXEN_BRDTYPE_P3_10G_TP:
+               adapter->msix_supported = !!use_msi_x;
+               if (adapter->ahw.board_type == NETXEN_NIC_XGBE)
+                       adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_10G;
+               else
+                       adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G;
+               break;
+
        default:
                adapter->msix_supported = 0;
                adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G;
@@ -272,10 +281,15 @@ static void netxen_check_options(struct netxen_adapter *adapter)
 static int
 netxen_check_hw_init(struct netxen_adapter *adapter, int first_boot)
 {
-       int ret = 0;
+       u32 val, timeout;
 
        if (first_boot == 0x55555555) {
                /* This is the first boot after power up */
+               adapter->pci_write_normalize(adapter,
+                       NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC);
+
+               if (!NX_IS_REVISION_P2(adapter->ahw.revision_id))
+                       return 0;
 
                /* PCI bus master workaround */
                adapter->hw_read_wx(adapter,
@@ -295,18 +309,26 @@ netxen_check_hw_init(struct netxen_adapter *adapter, int first_boot)
                        /* clear the register for future unloads/loads */
                        adapter->pci_write_normalize(adapter,
                                        NETXEN_CAM_RAM(0x1fc), 0);
-                       ret = -1;
+                       return -EIO;
                }
 
-               if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
-                       /* Start P2 boot loader */
-                       adapter->pci_write_normalize(adapter,
-                               NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC);
-                       adapter->pci_write_normalize(adapter,
-                                       NETXEN_ROMUSB_GLB_PEGTUNE_DONE, 1);
-               }
+               /* Start P2 boot loader */
+               val = adapter->pci_read_normalize(adapter,
+                               NETXEN_ROMUSB_GLB_PEGTUNE_DONE);
+               adapter->pci_write_normalize(adapter,
+                               NETXEN_ROMUSB_GLB_PEGTUNE_DONE, val | 0x1);
+               timeout = 0;
+               do {
+                       msleep(1);
+                       val = adapter->pci_read_normalize(adapter,
+                                       NETXEN_CAM_RAM(0x1fc));
+
+                       if (++timeout > 5000)
+                               return -EIO;
+
+               } while (val == NETXEN_BDINFO_MAGIC);
        }
-       return ret;
+       return 0;
 }
 
 static void netxen_set_port_mode(struct netxen_adapter *adapter)
@@ -713,17 +735,18 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        SET_ETHTOOL_OPS(netdev, &netxen_nic_ethtool_ops);
 
-       /* ScatterGather support */
-       netdev->features = NETIF_F_SG;
-       netdev->features |= NETIF_F_IP_CSUM;
-       netdev->features |= NETIF_F_TSO;
+       netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO);
+       netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO);
+
        if (NX_IS_REVISION_P3(revision_id)) {
-               netdev->features |= NETIF_F_IPV6_CSUM;
-               netdev->features |= NETIF_F_TSO6;
+               netdev->features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6);
+               netdev->vlan_features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6);
        }
 
-       if (adapter->pci_using_dac)
+       if (adapter->pci_using_dac) {
                netdev->features |= NETIF_F_HIGHDMA;
+               netdev->vlan_features |= NETIF_F_HIGHDMA;
+       }
 
        /*
         * Set the CRB window to invalid. If any register in window 0 is
@@ -785,8 +808,8 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                                                CRB_CMDPEG_STATE, 0);
                        netxen_pinit_from_rom(adapter, 0);
                        msleep(1);
-                       netxen_load_firmware(adapter);
                }
+               netxen_load_firmware(adapter);
 
                if (NX_IS_REVISION_P3(revision_id))
                        netxen_pcie_strap_init(adapter);
@@ -802,13 +825,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
                }
 
-               if ((first_boot == 0x55555555) &&
-                       (NX_IS_REVISION_P2(revision_id))) {
-                       /* Unlock the HW, prompting the boot sequence */
-                       adapter->pci_write_normalize(adapter,
-                                       NETXEN_ROMUSB_GLB_PEGTUNE_DONE, 1);
-               }
-
                err = netxen_initialize_adapter_offload(adapter);
                if (err)
                        goto err_out_iounmap;
@@ -822,7 +838,9 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                adapter->pci_write_normalize(adapter, CRB_DRIVER_VERSION, i);
 
                /* Handshake with the card before we register the devices. */
-               netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
+               err = netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
+               if (err)
+                       goto err_out_free_offload;
 
        }       /* first_driver */
 
@@ -926,6 +944,7 @@ err_out_disable_msi:
        if (adapter->flags & NETXEN_NIC_MSI_ENABLED)
                pci_disable_msi(pdev);
 
+err_out_free_offload:
        if (first_driver)
                netxen_free_adapter_offload(adapter);
 
@@ -969,6 +988,9 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
                netxen_free_hw_resources(adapter);
                netxen_release_rx_buffers(adapter);
                netxen_free_sw_resources(adapter);
+
+               if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+                       netxen_p3_free_mac_list(adapter);
        }
 
        if (adapter->portnum == 0)
@@ -984,8 +1006,10 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
 
        iounmap(adapter->ahw.db_base);
        iounmap(adapter->ahw.pci_base0);
-       iounmap(adapter->ahw.pci_base1);
-       iounmap(adapter->ahw.pci_base2);
+       if (adapter->ahw.pci_base1 != NULL)
+               iounmap(adapter->ahw.pci_base1);
+       if (adapter->ahw.pci_base2 != NULL)
+               iounmap(adapter->ahw.pci_base2);
 
        pci_release_regions(pdev);
        pci_disable_device(pdev);
@@ -1143,6 +1167,14 @@ static bool netxen_tso_check(struct net_device *netdev,
 {
        bool tso = false;
        u8 opcode = TX_ETHER_PKT;
+       __be16 protocol = skb->protocol;
+       u16 flags = 0;
+
+       if (protocol == cpu_to_be16(ETH_P_8021Q)) {
+               struct vlan_ethhdr *vh = (struct vlan_ethhdr *)skb->data;
+               protocol = vh->h_vlan_encapsulated_proto;
+               flags = FLAGS_VLAN_TAGGED;
+       }
 
        if ((netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) &&
                        skb_shinfo(skb)->gso_size > 0) {
@@ -1151,21 +1183,21 @@ static bool netxen_tso_check(struct net_device *netdev,
                desc->total_hdr_length =
                        skb_transport_offset(skb) + tcp_hdrlen(skb);
 
-               opcode = (skb->protocol == htons(ETH_P_IPV6)) ?
+               opcode = (protocol == cpu_to_be16(ETH_P_IPV6)) ?
                                TX_TCP_LSO6 : TX_TCP_LSO;
                tso = true;
 
        } else if (skb->ip_summed == CHECKSUM_PARTIAL) {
                u8 l4proto;
 
-               if (skb->protocol == htons(ETH_P_IP)) {
+               if (protocol == cpu_to_be16(ETH_P_IP)) {
                        l4proto = ip_hdr(skb)->protocol;
 
                        if (l4proto == IPPROTO_TCP)
                                opcode = TX_TCP_PKT;
                        else if(l4proto == IPPROTO_UDP)
                                opcode = TX_UDP_PKT;
-               } else if (skb->protocol == htons(ETH_P_IPV6)) {
+               } else if (protocol == cpu_to_be16(ETH_P_IPV6)) {
                        l4proto = ipv6_hdr(skb)->nexthdr;
 
                        if (l4proto == IPPROTO_TCP)
@@ -1176,10 +1208,28 @@ static bool netxen_tso_check(struct net_device *netdev,
        }
        desc->tcp_hdr_offset = skb_transport_offset(skb);
        desc->ip_hdr_offset = skb_network_offset(skb);
-       netxen_set_tx_flags_opcode(desc, 0, opcode);
+       netxen_set_tx_flags_opcode(desc, flags, opcode);
        return tso;
 }
 
+static void
+netxen_clean_tx_dma_mapping(struct pci_dev *pdev,
+               struct netxen_cmd_buffer *pbuf, int last)
+{
+       int k;
+       struct netxen_skb_frag *buffrag;
+
+       buffrag = &pbuf->frag_array[0];
+       pci_unmap_single(pdev, buffrag->dma,
+                       buffrag->length, PCI_DMA_TODEVICE);
+
+       for (k = 1; k < last; k++) {
+               buffrag = &pbuf->frag_array[k];
+               pci_unmap_page(pdev, buffrag->dma,
+                       buffrag->length, PCI_DMA_TODEVICE);
+       }
+}
+
 static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 {
        struct netxen_adapter *adapter = netdev_priv(netdev);
@@ -1188,6 +1238,8 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
        struct netxen_cmd_buffer *pbuf;
        struct netxen_skb_frag *buffrag;
        struct cmd_desc_type0 *hwdesc;
+       struct pci_dev *pdev = adapter->pdev;
+       dma_addr_t temp_dma;
        int i, k;
 
        u32 producer, consumer;
@@ -1220,8 +1272,12 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
        pbuf->skb = skb;
        pbuf->frag_count = frag_count;
        buffrag = &pbuf->frag_array[0];
-       buffrag->dma = pci_map_single(adapter->pdev, skb->data, first_seg_len,
+       temp_dma = pci_map_single(pdev, skb->data, first_seg_len,
                                      PCI_DMA_TODEVICE);
+       if (pci_dma_mapping_error(pdev, temp_dma))
+               goto drop_packet;
+
+       buffrag->dma = temp_dma;
        buffrag->length = first_seg_len;
        netxen_set_tx_frags_len(hwdesc, frag_count, skb->len);
        netxen_set_tx_port(hwdesc, adapter->portnum);
@@ -1233,7 +1289,6 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
                struct skb_frag_struct *frag;
                int len, temp_len;
                unsigned long offset;
-               dma_addr_t temp_dma;
 
                /* move to next desc. if there is a need */
                if ((i & 0x3) == 0) {
@@ -1249,8 +1304,12 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
                offset = frag->page_offset;
 
                temp_len = len;
-               temp_dma = pci_map_page(adapter->pdev, frag->page, offset,
+               temp_dma = pci_map_page(pdev, frag->page, offset,
                                        len, PCI_DMA_TODEVICE);
+               if (pci_dma_mapping_error(pdev, temp_dma)) {
+                       netxen_clean_tx_dma_mapping(pdev, pbuf, i);
+                       goto drop_packet;
+               }
 
                buffrag++;
                buffrag->dma = temp_dma;
@@ -1325,6 +1384,11 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
        netdev->trans_start = jiffies;
 
        return NETDEV_TX_OK;
+
+drop_packet:
+       adapter->stats.txdropped++;
+       dev_kfree_skb_any(skb);
+       return NETDEV_TX_OK;
 }
 
 static int netxen_nic_check_temp(struct netxen_adapter *adapter)
@@ -1396,6 +1460,8 @@ static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter)
                        netif_carrier_off(netdev);
                        netif_stop_queue(netdev);
                }
+
+               netxen_nic_set_link_parameters(adapter);
        } else if (!adapter->ahw.linkup && linkup) {
                printk(KERN_INFO "%s: %s NIC Link is up\n",
                       netxen_nic_driver_name, netdev->name);
@@ -1404,6 +1470,8 @@ static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter)
                        netif_carrier_on(netdev);
                        netif_wake_queue(netdev);
                }
+
+               netxen_nic_set_link_parameters(adapter);
        }
 }
 
@@ -1572,7 +1640,7 @@ static int netxen_nic_poll(struct napi_struct *napi, int budget)
        }
 
        if ((work_done < budget) && tx_complete) {
-               netif_rx_complete(&adapter->napi);
+               napi_complete(&adapter->napi);
                netxen_nic_enable_int(adapter);
        }
 
This page took 0.035083 seconds and 5 git commands to generate.