Updated code for the NetEffect NE020 adapter.

Updates include:
- Support for userspace/virtual WQs.
- PowerPC
- Support for multiple debugging levels
- Many, many cosmetic changes inline with kernel.org standards

Diffs for nes_nic.c

Signed-off-by: Glenn Grundstrom <[EMAIL PROTECTED]>

---
diff --git a/drivers/infiniband/hw/nes/nes_nic.c 
b/drivers/infiniband/hw/nes/nes_nic.c
index 2d759c4..d75b327 100644
--- a/drivers/infiniband/hw/nes/nes_nic.c
+++ b/drivers/infiniband/hw/nes/nes_nic.c
@@ -92,7 +92,40 @@ static const u32 default_msg = NETIF_MSG_DRV | 
NETIF_MSG_PROBE | NETIF_MSG_LINK
                | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN;
 static int debug = -1;
 
-static int rdma_enabled = 0;
+extern atomic_t cm_connects;
+extern atomic_t cm_accepts;
+extern atomic_t cm_disconnects;
+extern atomic_t cm_closes;
+extern atomic_t cm_connecteds;
+extern atomic_t cm_connect_reqs;
+extern atomic_t cm_rejects;
+extern atomic_t mod_qp_timouts;
+extern atomic_t qps_created;
+extern atomic_t qps_destroyed;
+extern atomic_t sw_qps_destroyed;
+extern u32 mh_detected;
+extern u32 mh_pauses_sent;
+extern u32 cm_packets_sent;
+extern u32 cm_packets_bounced;
+extern u32 cm_packets_created;
+extern u32 cm_packets_received;
+extern u32 cm_packets_dropped;
+extern u32 cm_packets_retrans;
+extern u32 cm_listens_created;
+extern u32 cm_listens_destroyed;
+extern u32 cm_backlog_drops;
+extern atomic_t cm_nodes_created;
+extern atomic_t cm_nodes_destroyed;
+extern atomic_t cm_accel_dropped_pkts;
+extern atomic_t cm_resets_recvd;
+extern u32 int_mod_timer_init;
+extern u32 int_mod_cq_depth_256;
+extern u32 int_mod_cq_depth_128;
+extern u32 int_mod_cq_depth_32;
+extern u32 int_mod_cq_depth_24;
+extern u32 int_mod_cq_depth_16;
+extern u32 int_mod_cq_depth_4;
+extern u32 int_mod_cq_depth_1;
 
 static int nes_netdev_open(struct net_device *);
 static int nes_netdev_stop(struct net_device *);
@@ -122,7 +155,7 @@ static int nes_netdev_poll(struct net_device* netdev, int* 
budget)
        netdev->quota -= nesvnic->rx_cqes_completed;
        *budget -= nesvnic->rx_cqes_completed;
 
-       if (0 == nesvnic->cqes_pending) {
+       if (nesvnic->cqes_pending == 0) {
                netif_rx_complete(netdev);
                /* clear out completed cqes and arm */
                nes_write32(nesdev->regs+NES_CQE_ALLOC, 
NES_CQE_ALLOC_NOTIFY_NEXT |
@@ -136,7 +169,7 @@ static int nes_netdev_poll(struct net_device* netdev, int* 
budget)
                                nesvnic->netdev->name);
        }
 
-       return((0 == nesvnic->cqes_pending) ? 0 : 1);
+       return (nesvnic->cqes_pending == 0) ? 0 : 1;
 }
 #endif
 
@@ -190,9 +223,9 @@ static int nes_netdev_open(struct net_device *netdev)
        nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_ACTIVE);
        nic_active |= nic_active_bit;
        nes_write_indexed(nesdev, NES_IDX_NIC_ACTIVE, nic_active);
-       nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL);
+       nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_MULTICAST_ENABLE);
        nic_active |= nic_active_bit;
-       nes_write_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL, nic_active);
+       nes_write_indexed(nesdev, NES_IDX_NIC_MULTICAST_ENABLE, nic_active);
        nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_BROADCAST_ON);
        nic_active |= nic_active_bit;
        nes_write_indexed(nesdev, NES_IDX_NIC_BROADCAST_ON, nic_active);
@@ -204,7 +237,6 @@ static int nes_netdev_open(struct net_device *netdev)
        macaddr_low += ((u32)netdev->dev_addr[4]) << 8;
        macaddr_low += (u32)netdev->dev_addr[5];
 
-#define NES_MAX_PORT_COUNT 4
        /* Program the various MAC regs */
        for (i = 0; i < NES_MAX_PORT_COUNT; i++) {
                if (nesvnic->qp_nic_index[i] == 0xf) {
@@ -264,8 +296,9 @@ static int nes_netdev_stop(struct net_device *netdev)
        u32 nic_active_mask;
        u32 nic_active;
 
-       nes_debug(NES_DBG_SHUTDOWN, "\n");
-       if (0 == nesvnic->netdev_open)
+       nes_debug(NES_DBG_SHUTDOWN, "nesvnic=%p, nesdev=%p, netdev=%p %s\n",
+                       nesvnic, nesdev, netdev, netdev->name);
+       if (nesvnic->netdev_open == 0)
                return 0;
 
        if (netif_msg_ifdown(nesvnic))
@@ -273,7 +306,7 @@ static int nes_netdev_stop(struct net_device *netdev)
 
        /* Disable network packets */
        netif_stop_queue(netdev);
-       if ((nesdev->netdev[0] == netdev)&(nesvnic->logical_port == 
nesdev->mac_index)) {
+       if ((nesdev->netdev[0] == netdev) & (nesvnic->logical_port == 
nesdev->mac_index)) {
                nes_write_indexed(nesdev,
                                NES_IDX_MAC_INT_MASK+(0x200*nesdev->mac_index), 
0xffffffff);
        }
@@ -287,6 +320,12 @@ static int nes_netdev_stop(struct net_device *netdev)
        nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL);
        nic_active &= nic_active_mask;
        nes_write_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL, nic_active);
+       nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_MULTICAST_ENABLE);
+       nic_active &= nic_active_mask;
+       nes_write_indexed(nesdev, NES_IDX_NIC_MULTICAST_ENABLE, nic_active);
+       nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL);
+       nic_active &= nic_active_mask;
+       nes_write_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL, nic_active);
        nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_BROADCAST_ON);
        nic_active &= nic_active_mask;
        nes_write_indexed(nesdev, NES_IDX_NIC_BROADCAST_ON, nic_active);
@@ -296,7 +335,6 @@ static int nes_netdev_stop(struct net_device *netdev)
                nes_destroy_ofa_device(nesvnic->nesibdev);
                nesvnic->nesibdev = NULL;
                nesvnic->of_device_registered = 0;
-               rdma_enabled = 0;
        }
        nes_destroy_nic_qp(nesvnic);
 
@@ -317,9 +355,7 @@ static int nes_nic_send(struct sk_buff *skb, struct 
net_device *netdev)
        struct nes_hw_nic_sq_wqe *nic_sqe;
 #ifdef NETIF_F_TSO
        struct tcphdr *tcph;
-       /* struct udphdr *udph; */
 #endif
-//     u64 *wqe_fragment_address;
        u16 *wqe_fragment_length;
        u32 wqe_misc;
        u16 wqe_fragment_index = 1;     /* first fragment (0) is used by copy 
buffer */
@@ -343,18 +379,14 @@ static int nes_nic_send(struct sk_buff *skb, struct 
net_device *netdev)
        /*      wqe_fragment_address = (u64 
*)&nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_LOW_IDX]; */
 
        if (skb->ip_summed == CHECKSUM_PARTIAL) {
-#ifdef OFED_1_2
-               tcph = skb->h.th;
-#else
                tcph = tcp_hdr(skb);
-#endif
                if (1) {
 #ifdef NETIF_F_TSO
-                       if (nes_skb_is_gso(skb)) {
+                       if (skb_is_gso(skb)) {
                                /* nes_debug(NES_DBG_NIC_TX, "%s: TSO 
request... seg size = %u\n",
-                                               netdev->name, 
nes_skb_is_gso(skb)); */
+                                               netdev->name, skb_is_gso(skb)); 
*/
                                wqe_misc |= NES_NIC_SQ_WQE_LSO_ENABLE |
-                                               NES_NIC_SQ_WQE_COMPLETION | 
(u16)nes_skb_is_gso(skb);
+                                               NES_NIC_SQ_WQE_COMPLETION | 
(u16)skb_is_gso(skb);
                                nic_sqe->wqe_words[NES_NIC_SQ_WQE_LSO_INFO_IDX] 
=
                                                cpu_to_le32(((u32)tcph->doff) |
                                                (((u32)(((unsigned char *)tcph) 
- skb->data)) << 4));
@@ -383,6 +415,7 @@ static int nes_nic_send(struct sk_buff *skb, struct 
net_device *netdev)
                        nesvnic->tx_sw_dropped++;
                        return NETDEV_TX_LOCKED;
                }
+               set_bit(nesnic->sq_head, nesnic->first_frag_overflow);
                bus_address = pci_map_single(nesdev->pcidev, skb->data + 
NES_FIRST_FRAG_SIZE,
                                skb_headlen(skb) - NES_FIRST_FRAG_SIZE, 
PCI_DMA_TODEVICE);
                wqe_fragment_length[wqe_fragment_index++] =
@@ -444,6 +477,7 @@ static int nes_netdev_start_xmit(struct sk_buff *skb, 
struct net_device *netdev)
 #define NES_MAX_TSO_FRAGS 18
        /* 64K segment plus overflow on each side */
        dma_addr_t tso_bus_address[NES_MAX_TSO_FRAGS];
+       dma_addr_t bus_address;
        u32 tso_frag_index;
        u32 tso_frag_count;
        u32 tso_wqe_length;
@@ -454,6 +488,8 @@ static int nes_netdev_start_xmit(struct sk_buff *skb, 
struct net_device *netdev)
        struct iphdr *iph;
        unsigned long flags;
        u16 *wqe_fragment_length;
+       u32 nr_frags;
+       u32 original_first_length;
 //     u64 *wqe_fragment_address;
        /* first fragment (0) is used by copy buffer */
        u16 wqe_fragment_index=1;
@@ -466,12 +502,11 @@ static int nes_netdev_start_xmit(struct sk_buff *skb, 
struct net_device *netdev)
        u32 old_head;
        u32 wqe_misc;
 
-       if (nes_debug_level & NES_DBG_NIC_TX) {
-               nes_debug(NES_DBG_NIC_TX, "%s Request to tx NIC packet length 
%u, headlen %u,"
-                               " (%u frags), tso_size=%u\n",
-                               netdev->name, skb->len, skb_headlen(skb),
-                               skb_shinfo(skb)->nr_frags, nes_skb_is_gso(skb));
-       }
+       /* nes_debug(NES_DBG_NIC_TX, "%s Request to tx NIC packet length %u, 
headlen %u,"
+                       " (%u frags), tso_size=%u\n",
+                       netdev->name, skb->len, skb_headlen(skb),
+                       skb_shinfo(skb)->nr_frags, skb_is_gso(skb));
+       */
        local_irq_save(flags);
        if (!spin_trylock(&nesnic->sq_lock)) {
                local_irq_restore(flags);
@@ -487,16 +522,20 @@ static int nes_netdev_start_xmit(struct sk_buff *skb, 
struct net_device *netdev)
                return NETDEV_TX_BUSY;
        }
 
+       nr_frags = skb_shinfo(skb)->nr_frags;
+       if (skb_headlen(skb) > NES_FIRST_FRAG_SIZE) {
+               nr_frags++;
+       }
        /* Check if too many fragments */
-       if (unlikely((skb_shinfo(skb)->nr_frags) > 4)) {
+       if (unlikely((nr_frags > 4))) {
 #ifdef NETIF_F_TSO
-               if (nes_skb_is_gso(skb) && (skb_headlen(skb) <= 
NES_FIRST_FRAG_SIZE)) {
+               if (skb_is_gso(skb)) {
                        nesvnic->segmented_tso_requests++;
                        nesvnic->tso_requests++;
                        old_head = nesnic->sq_head;
                        /* Basically 4 fragments available per WQE with 
extended fragments */
-                       wqes_needed = skb_shinfo(skb)->nr_frags >> 2;
-                       wqes_needed += (skb_shinfo(skb)->nr_frags&3)?1:0;
+                       wqes_needed = nr_frags >> 2;
+                       wqes_needed += (nr_frags&3)?1:0;
                        wqes_available = 
(((nesnic->sq_tail+nesnic->sq_size)-nesnic->sq_head) - 1) &
                                        (nesnic->sq_size - 1);
 
@@ -519,18 +558,10 @@ static int nes_netdev_start_xmit(struct sk_buff *skb, 
struct net_device *netdev)
                        }
 
                        tso_frag_index = 0;
-#ifdef OFED_1_2
-                       curr_tcp_seq = ntohl(skb->h.th->seq);
-#else
                        curr_tcp_seq = ntohl(tcp_hdr(skb)->seq);
-#endif
-#ifdef OFED_1_2
-                       hoffset = skb->h.raw - skb->data;
-                       nhoffset = skb->nh.raw - skb->data;
-#else
                        hoffset = skb_transport_header(skb) - skb->data;
                        nhoffset = skb_network_header(skb) - skb->data;
-#endif
+                       original_first_length = hoffset + ((((struct tcphdr 
*)skb_transport_header(skb))->doff)<<2);
 
                        for (wqe_count=0; wqe_count<((u32)wqes_needed); 
wqe_count++) {
                                tso_wqe_length = 0;
@@ -548,22 +579,20 @@ static int nes_netdev_start_xmit(struct sk_buff *skb, 
struct net_device *netdev)
 
                                /* bump past the vlan tag */
                                wqe_fragment_length++;
-//                             wqe_fragment_address =
-//                                             (u64 
*)&nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_LOW_IDX];
 
                                /* Assumes header totally fits in allocated 
buffer and is in first fragment */
-                               if (skb_headlen(skb) > NES_FIRST_FRAG_SIZE) {
-                                       nes_debug(NES_DBG_NIC_TX, "ERROR: SKB 
header too big, skb_headlen=%u, FIRST_FRAG_SIZE=%u\n",
-                                                       skb_headlen(skb), 
NES_FIRST_FRAG_SIZE);
+                               if (original_first_length > 
NES_FIRST_FRAG_SIZE) {
+                                       nes_debug(NES_DBG_NIC_TX, "ERROR: SKB 
header too big, headlen=%u, FIRST_FRAG_SIZE=%u\n",
+                                                       original_first_length, 
NES_FIRST_FRAG_SIZE);
                                        nes_debug(NES_DBG_NIC_TX, "%s Request 
to tx NIC packet length %u, headlen %u,"
                                                        " (%u frags), 
tso_size=%u\n",
                                                        netdev->name,
                                                        skb->len, 
skb_headlen(skb),
-                                                       
skb_shinfo(skb)->nr_frags, nes_skb_is_gso(skb));
+                                                       
skb_shinfo(skb)->nr_frags, skb_is_gso(skb));
                                }
                                
memcpy(&nesnic->first_frag_vbase[nesnic->sq_head].buffer,
                                                skb->data, min(((unsigned 
int)NES_FIRST_FRAG_SIZE),
-                                               skb_headlen(skb)));
+                                               original_first_length));
                                iph = (struct iphdr *)
                                
(&nesnic->first_frag_vbase[nesnic->sq_head].buffer[nhoffset]);
                                tcph = (struct tcphdr *)
@@ -579,9 +608,21 @@ static int nes_netdev_start_xmit(struct sk_buff *skb, 
struct net_device *netdev)
                                }
                                tcph->seq = htonl(curr_tcp_seq);
                                wqe_fragment_length[0] = 
cpu_to_le16(min(((unsigned int)NES_FIRST_FRAG_SIZE),
-                                               skb_headlen(skb)));
-
-                               for (wqe_fragment_index = 1; wqe_fragment_index 
< 5;) {
+                                               original_first_length));
+
+                               wqe_fragment_index = 1;
+                               if ((wqe_count==0) && (skb_headlen(skb) > 
original_first_length)) {
+                                       set_bit(nesnic->sq_head, 
nesnic->first_frag_overflow);
+                                       bus_address = 
pci_map_single(nesdev->pcidev, skb->data + original_first_length,
+                                                       skb_headlen(skb) - 
original_first_length, PCI_DMA_TODEVICE);
+                                       
wqe_fragment_length[wqe_fragment_index++] =
+                                               cpu_to_le16(skb_headlen(skb) - 
original_first_length);
+                                       wqe_fragment_length[wqe_fragment_index] 
= 0;
+                                       
nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG1_LOW_IDX] = 
cpu_to_le32((u32)((u64)(bus_address)));
+                                       
nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG1_HIGH_IDX] = 
cpu_to_le32((u32)(((u64)(bus_address))>>32));
+                                       tso_wqe_length += skb_headlen(skb) - 
original_first_length;
+                               }
+                               while (wqe_fragment_index < 5) {
                                        wqe_fragment_length[wqe_fragment_index] 
=
                                                        
cpu_to_le16(skb_shinfo(skb)->frags[tso_frag_index].size);
                                        
nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_LOW_IDX+(2*wqe_fragment_index)] =
@@ -600,19 +641,19 @@ static int nes_netdev_start_xmit(struct sk_buff *skb, 
struct net_device *netdev)
                                } else {
                                        nesnic->tx_skb[nesnic->sq_head] = NULL;
                                }
-                               wqe_misc |= NES_NIC_SQ_WQE_COMPLETION | 
(u16)nes_skb_is_gso(skb);
-                               if ((tso_wqe_length + skb_headlen(skb)) > 
nes_skb_is_gso(skb)) {
-                                       wqe_misc |= NES_NIC_SQ_WQE_LSO_ENABLE;
-                               } else {
-                                       iph->tot_len = htons(tso_wqe_length + 
skb_headlen(skb) - nhoffset);
-                               }
+                               wqe_misc |= NES_NIC_SQ_WQE_COMPLETION | 
(u16)skb_is_gso(skb);
+                               if ((tso_wqe_length + original_first_length) > 
skb_is_gso(skb)) {
+                                       wqe_misc |= NES_NIC_SQ_WQE_LSO_ENABLE;
+                               } else {
+                                       iph->tot_len = htons(tso_wqe_length + 
original_first_length - nhoffset);
+                               }
 
                                nic_sqe->wqe_words[NES_NIC_SQ_WQE_MISC_IDX] = 
cpu_to_le32(wqe_misc);
                                nic_sqe->wqe_words[NES_NIC_SQ_WQE_LSO_INFO_IDX] 
=
                                                cpu_to_le32(((u32)tcph->doff) | 
(((u32)hoffset) << 4));
 
                                
nic_sqe->wqe_words[NES_NIC_SQ_WQE_TOTAL_LENGTH_IDX] =
-                                               
cpu_to_le32(tso_wqe_length+skb_headlen(skb));
+                                               
cpu_to_le32(tso_wqe_length+original_first_length);
                                curr_tcp_seq += tso_wqe_length;
                                nesnic->sq_head++;
                                nesnic->sq_head &= nesnic->sq_size-1;
@@ -620,21 +661,11 @@ static int nes_netdev_start_xmit(struct sk_buff *skb, 
struct net_device *netdev)
                } else {
 #endif
                        nesvnic->linearized_skbs++;
-#ifdef OFED_1_2
-                       hoffset = skb->h.raw - skb->data;
-                       nhoffset = skb->nh.raw - skb->data;
-#else
                        hoffset = skb_transport_header(skb) - skb->data;
                        nhoffset = skb_network_header(skb) - skb->data;
-#endif
-                       nes_skb_linearize(skb);
-#ifdef OFED_1_2
-                       skb->h.raw = skb->data + hoffset;
-                       skb->nh.raw = skb->data + nhoffset;
-#else
+                       skb_linearize(skb);
                        skb_set_transport_header(skb, hoffset);
                        skb_set_network_header(skb, nhoffset);
-#endif
                        send_rc = nes_nic_send(skb, netdev);
                        if (send_rc != NETDEV_TX_OK) {
                                spin_unlock_irqrestore(&nesnic->sq_lock, flags);
@@ -767,28 +798,158 @@ static void nes_netdev_tx_timeout(struct net_device 
*netdev)
 }
 
 
+#ifdef HAVE_SET_MAC_ADDR
 /**
  * nes_netdev_set_mac_address
  */
 static int nes_netdev_set_mac_address(struct net_device *netdev, void *p)
 {
-       return -1;
+       struct nes_vnic *nesvnic = netdev_priv(netdev);
+       struct nes_device *nesdev = nesvnic->nesdev;
+       struct sockaddr *mac_addr = p;
+       int i;
+       u32 macaddr_low;
+       u16 macaddr_high;
+
+       if (!is_valid_ether_addr(mac_addr->sa_data))
+               return -EADDRNOTAVAIL;
+
+       memcpy(netdev->dev_addr, mac_addr->sa_data, netdev->addr_len);
+       printk(PFX "%s: Address length = %d, Address = 
%02X%02X%02X%02X%02X%02X..\n",
+                  __FUNCTION__, netdev->addr_len,
+                  mac_addr->sa_data[0], mac_addr->sa_data[1],
+                  mac_addr->sa_data[2], mac_addr->sa_data[3],
+                  mac_addr->sa_data[4], mac_addr->sa_data[5]);
+       macaddr_high = ((u16)netdev->dev_addr[0]) << 8;
+       macaddr_high += (u16)netdev->dev_addr[1];
+       macaddr_low = ((u32)netdev->dev_addr[2]) << 24;
+       macaddr_low += ((u32)netdev->dev_addr[3]) << 16;
+       macaddr_low += ((u32)netdev->dev_addr[4]) << 8;
+       macaddr_low += (u32)netdev->dev_addr[5];
+
+       for (i = 0; i < NES_MAX_PORT_COUNT; i++) {
+               if (nesvnic->qp_nic_index[i] == 0xf) {
+                       break;
+               }
+               nes_write_indexed(nesdev,
+                               NES_IDX_PERFECT_FILTER_LOW + 
(nesvnic->qp_nic_index[i] * 8),
+                               macaddr_low);
+               nes_write_indexed(nesdev,
+                               NES_IDX_PERFECT_FILTER_HIGH + 
(nesvnic->qp_nic_index[i] * 8),
+                               (u32)macaddr_high | NES_MAC_ADDR_VALID |
+                               ((((u32)nesvnic->nic_index) << 16)));
+       }
+       return 0;
 }
+#endif
 
 
+#ifdef HAVE_MULTICAST
 /**
- * nes_netdev_change_mtu
+ * nes_netdev_set_multicast_list
  */
-static int nes_netdev_change_mtu(struct net_device *netdev, int new_mtu)
+void nes_netdev_set_multicast_list(struct net_device *netdev)
 {
        struct nes_vnic *nesvnic = netdev_priv(netdev);
-       int ret = 0;
+       struct nes_device *nesdev = nesvnic->nesdev;
+       struct dev_mc_list *multicast_addr;
+       u32 nic_active_bit;
+       u32 nic_active;
+       u32 perfect_filter_register_address;
+       u32 macaddr_low;
+       u16 macaddr_high;
+       u8 mc_all_on = 0;
+       u8 mc_index;
+
+       nic_active_bit = 1 << nesvnic->nic_index;
+
+       if (netdev->flags & IFF_PROMISC) {
+               nic_active = nes_read_indexed(nesdev, 
NES_IDX_NIC_MULTICAST_ALL);
+               nic_active |= nic_active_bit;
+               nes_write_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL, 
nic_active);
+               nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL);
+               nic_active |= nic_active_bit;
+               nes_write_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL, nic_active);
+               mc_all_on = 1;
+       } else if ((netdev->flags & IFF_ALLMULTI) || (netdev->mc_count > 
NES_MULTICAST_PF_MAX) ||
+                          (nesvnic->nic_index > 3)) {
+               nic_active = nes_read_indexed(nesdev, 
NES_IDX_NIC_MULTICAST_ALL);
+               nic_active |= nic_active_bit;
+               nes_write_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL, 
nic_active);
+               nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL);
+               nic_active &= ~nic_active_bit;
+               nes_write_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL, nic_active);
+               mc_all_on = 1;
+       } else {
+               nic_active = nes_read_indexed(nesdev, 
NES_IDX_NIC_MULTICAST_ALL);
+               nic_active &= ~nic_active_bit;
+               nes_write_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL, 
nic_active);
+               nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL);
+               nic_active &= ~nic_active_bit;
+               nes_write_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL, nic_active);
+       }
+
+       nes_debug(NES_DBG_NIC_RX, "Number of MC entries = %d, Promiscous = %d, 
All Multicast = %d.\n",
+                         netdev->mc_count, (netdev->flags & IFF_PROMISC)?1:0,
+                         (netdev->flags & IFF_ALLMULTI)?1:0);
+       if (!mc_all_on) {
+               multicast_addr = netdev->mc_list;
+               perfect_filter_register_address = NES_IDX_PERFECT_FILTER_LOW + 
0x80;
+               perfect_filter_register_address += nesvnic->nic_index*0x40;
+               for (mc_index=0; mc_index < NES_MULTICAST_PF_MAX; mc_index++) {
+                       if (multicast_addr) {
+                               nes_debug(NES_DBG_NIC_RX, "Assigning MC Address 
= %02X%02X%02X%02X%02X%02X to register 0x%04X\n",
+                                                 multicast_addr->dmi_addr[0], 
multicast_addr->dmi_addr[1],
+                                                 multicast_addr->dmi_addr[2], 
multicast_addr->dmi_addr[3],
+                                                 multicast_addr->dmi_addr[4], 
multicast_addr->dmi_addr[5],
+                                                 
perfect_filter_register_address+(mc_index * 8));
+                               macaddr_high = 
((u16)multicast_addr->dmi_addr[0]) << 8;
+                               macaddr_high += 
(u16)multicast_addr->dmi_addr[1];
+                               macaddr_low = 
((u32)multicast_addr->dmi_addr[2]) << 24;
+                               macaddr_low += 
((u32)multicast_addr->dmi_addr[3]) << 16;
+                               macaddr_low += 
((u32)multicast_addr->dmi_addr[4]) << 8;
+                               macaddr_low += (u32)multicast_addr->dmi_addr[5];
+                               nes_write_indexed(nesdev,
+                                               
perfect_filter_register_address+(mc_index * 8),
+                                               macaddr_low);
+                               nes_write_indexed(nesdev,
+                                               
perfect_filter_register_address+4+(mc_index * 8),
+                                               (u32)macaddr_high | 
NES_MAC_ADDR_VALID |
+                                               
((((u32)(1<<nesvnic->nic_index)) << 16)));
+                               multicast_addr = multicast_addr->next;
+                       } else {
+                               nes_debug(NES_DBG_NIC_RX, "Clearing MC Address 
at register 0x%04X\n",
+                                                 
perfect_filter_register_address+(mc_index * 8));
+                               nes_write_indexed(nesdev,
+                                               
perfect_filter_register_address+4+(mc_index * 8),
+                                               0);
+                       }
+               }
+       }
+}
+#endif
 
-       if ((new_mtu < ETH_ZLEN) || (new_mtu > max_mtu))
+
+/**
+ * nes_netdev_change_mtu
+ */
+static int nes_netdev_change_mtu(struct        net_device *netdev,     int     
new_mtu)
+{
+       struct nes_vnic *nesvnic = netdev_priv(netdev);
+       struct nes_device *nesdev =     nesvnic->nesdev;
+       int     ret     = 0;
+       u8 jumbomode=0;
+
+       if ((new_mtu < ETH_ZLEN) ||     (new_mtu > max_mtu))
                return -EINVAL;
 
-       netdev->mtu = new_mtu;
-       nesvnic->max_frame_size = new_mtu+ETH_HLEN;
+       netdev->mtu     = new_mtu;
+       nesvnic->max_frame_size = new_mtu+ETH_HLEN;
+
+       if (netdev->mtu > 1500) {
+               jumbomode=1;
+       }
+       nes_nic_init_timer_defaults(nesdev,     jumbomode);
 
        if (netif_running(netdev)) {
                nes_netdev_stop(netdev);
@@ -813,7 +974,6 @@ void nes_netdev_exit(struct nes_vnic *nesvnic)
        if ((nesvnic->rdma_enabled)&&(nesvnic->of_device_registered)) {
                nes_destroy_ofa_device( nesibdev );
                nesvnic->of_device_registered = 0;
-               rdma_enabled = 0;
                nesvnic->nesibdev = NULL;
        }
        unregister_netdev(netdev);
@@ -821,7 +981,7 @@ void nes_netdev_exit(struct nes_vnic *nesvnic)
 }
 
 
-#define NES_ETHTOOL_STAT_COUNT 52
+#define NES_ETHTOOL_STAT_COUNT 54
 static const char 
nes_ethtool_stringset[NES_ETHTOOL_STAT_COUNT][ETH_GSTRING_LEN] = {
        "Link Change Interrupts",
        "Linearized SKBs",
@@ -869,12 +1029,14 @@ static const char 
nes_ethtool_stringset[NES_ETHTOOL_STAT_COUNT][ETH_GSTRING_LEN]
        "CM Nodes Destroyed",
        "CM Accel Drops",
        "CM Resets Received",
-       "CQP Req Allocs",
-       "CQP Req Deallocs",
-       "CQP Req Dynamic Allocs",
-       "CQP Req Dynamic Deallocs",
-       "CQP Req Queues",
-       "CQP Req Redrives",
+       "Timer Inits",
+       "CQ Depth 1",
+       "CQ Depth 4",
+       "CQ Depth 16",
+       "CQ Depth 24",
+       "CQ Depth 32",
+       "CQ Depth 128",
+       "CQ Depth 256",
 };
 
 
@@ -1052,12 +1214,14 @@ static void nes_netdev_get_ethtool_stats(struct 
net_device *netdev,
        target_stat_values[43] = atomic_read(&cm_nodes_destroyed);
        target_stat_values[44] = atomic_read(&cm_accel_dropped_pkts);
        target_stat_values[45] = atomic_read(&cm_resets_recvd);
-       target_stat_values[46] = atomic_read(&cqp_reqs_allocated);
-       target_stat_values[47] = atomic_read(&cqp_reqs_freed);
-       target_stat_values[48] = atomic_read(&cqp_reqs_dynallocated);
-       target_stat_values[49] = atomic_read(&cqp_reqs_dynfreed);
-       target_stat_values[50] = atomic_read(&cqp_reqs_queued);
-       target_stat_values[51] = atomic_read(&cqp_reqs_redriven);
+       target_stat_values[46] = int_mod_timer_init;
+       target_stat_values[47] = int_mod_cq_depth_1;
+       target_stat_values[48] = int_mod_cq_depth_4;
+       target_stat_values[49] = int_mod_cq_depth_16;
+       target_stat_values[50] = int_mod_cq_depth_24;
+       target_stat_values[51] = int_mod_cq_depth_32;
+       target_stat_values[52] = int_mod_cq_depth_128;
+       target_stat_values[53] = int_mod_cq_depth_256;
 
 }
 
@@ -1085,16 +1249,48 @@ static void nes_netdev_get_drvinfo(struct net_device 
*netdev,
  * nes_netdev_set_coalesce
  */
 static int nes_netdev_set_coalesce(struct net_device *netdev,
-               struct ethtool_coalesce *et_coalesce)
+               struct ethtool_coalesce *et_coalesce)
 {
-       struct nes_vnic *nesvnic = netdev_priv(netdev);
-       struct nes_device *nesdev = nesvnic->nesdev;
+       struct nes_vnic *nesvnic = netdev_priv(netdev);
+       struct nes_device *nesdev =     nesvnic->nesdev;
+       struct nes_adapter *nesadapter = nesdev->nesadapter;
+       struct nes_hw_tune_timer *shared_timer = &nesadapter->tune_timer;
+       unsigned long flags;
+
+       spin_lock_irqsave(&nesadapter->periodic_timer_lock,     flags);
+       if (et_coalesce->rx_max_coalesced_frames_low) {
+               shared_timer->threshold_low      = 
et_coalesce->rx_max_coalesced_frames_low;
+       }
+       if (et_coalesce->rx_max_coalesced_frames_irq) {
+               shared_timer->threshold_target = 
et_coalesce->rx_max_coalesced_frames_irq;
+       }
+       if (et_coalesce->rx_max_coalesced_frames_high) {
+               shared_timer->threshold_high = 
et_coalesce->rx_max_coalesced_frames_high;
+       }
+       if (et_coalesce->rx_coalesce_usecs_low) {
+               shared_timer->timer_in_use_min = 
et_coalesce->rx_coalesce_usecs_low;
+       }
+       if (et_coalesce->rx_coalesce_usecs_high) {
+               shared_timer->timer_in_use_max = 
et_coalesce->rx_coalesce_usecs_high;
+       }
+       spin_unlock_irqrestore(&nesadapter->periodic_timer_lock, flags);
 
        /* using this to drive total interrupt moderation */
-       nesvnic->nesdev->et_rx_coalesce_usecs_irq = 
et_coalesce->rx_coalesce_usecs_irq;
-       if (nesdev->et_rx_coalesce_usecs_irq) {
-               nes_write32(nesdev->regs+NES_PERIODIC_CONTROL,
-                               0x80000000 | 
((u32)(nesdev->et_rx_coalesce_usecs_irq*8)));
+       nesadapter->et_rx_coalesce_usecs_irq = 
et_coalesce->rx_coalesce_usecs_irq;
+       if (et_coalesce->use_adaptive_rx_coalesce) {
+               nesadapter->et_use_adaptive_rx_coalesce = 1;
+               nesadapter->timer_int_limit     = NES_TIMER_INT_LIMIT_DYNAMIC;
+               nesadapter->et_rx_coalesce_usecs_irq = 0;
+               if (et_coalesce->pkt_rate_low) {
+                       nesadapter->et_pkt_rate_low     = 
et_coalesce->pkt_rate_low;
+               }
+       } else {
+               nesadapter->et_use_adaptive_rx_coalesce = 0;
+               nesadapter->timer_int_limit     = NES_TIMER_INT_LIMIT;
+               if (nesadapter->et_rx_coalesce_usecs_irq) {
+                       nes_write32(nesdev->regs+NES_PERIODIC_CONTROL,
+                                       0x80000000 | 
((u32)(nesadapter->et_rx_coalesce_usecs_irq*8)));
+               }
        }
        return 0;
 }
@@ -1104,18 +1300,33 @@ static int nes_netdev_set_coalesce(struct net_device 
*netdev,
  * nes_netdev_get_coalesce
  */
 static int nes_netdev_get_coalesce(struct net_device *netdev,
-               struct ethtool_coalesce *et_coalesce)
+               struct ethtool_coalesce *et_coalesce)
 {
-       struct nes_vnic *nesvnic = netdev_priv(netdev);
-       struct ethtool_coalesce temp_et_coalesce;
+       struct nes_vnic *nesvnic = netdev_priv(netdev);
+       struct nes_device *nesdev =     nesvnic->nesdev;
+       struct nes_adapter *nesadapter = nesdev->nesadapter;
+       struct ethtool_coalesce temp_et_coalesce;
+       struct nes_hw_tune_timer *shared_timer = &nesadapter->tune_timer;
+       unsigned long flags;
 
        memset(&temp_et_coalesce, 0, sizeof(temp_et_coalesce));
-       temp_et_coalesce.rx_coalesce_usecs_irq = 
nesvnic->nesdev->et_rx_coalesce_usecs_irq;
-       memcpy(et_coalesce, &temp_et_coalesce, sizeof(*et_coalesce));
+       temp_et_coalesce.rx_coalesce_usecs_irq = 
nesadapter->et_rx_coalesce_usecs_irq;
+       temp_et_coalesce.use_adaptive_rx_coalesce =     
nesadapter->et_use_adaptive_rx_coalesce;
+       temp_et_coalesce.rate_sample_interval = 
nesadapter->et_rate_sample_interval;
+       temp_et_coalesce.pkt_rate_low = nesadapter->et_pkt_rate_low;
+       spin_lock_irqsave(&nesadapter->periodic_timer_lock,     flags);
+       temp_et_coalesce.rx_max_coalesced_frames_low =  
shared_timer->threshold_low;
+       temp_et_coalesce.rx_max_coalesced_frames_irq =  
shared_timer->threshold_target;
+       temp_et_coalesce.rx_max_coalesced_frames_high = 
shared_timer->threshold_high;
+       temp_et_coalesce.rx_coalesce_usecs_low = shared_timer->timer_in_use_min;
+       temp_et_coalesce.rx_coalesce_usecs_high = 
shared_timer->timer_in_use_max;
+       spin_unlock_irqrestore(&nesadapter->periodic_timer_lock, flags);
+       memcpy(et_coalesce,     &temp_et_coalesce, sizeof(*et_coalesce));
        return 0;
 }
 
 
+
 /**
  * nes_netdev_get_pauseparam
  */
@@ -1125,8 +1336,8 @@ static void nes_netdev_get_pauseparam(struct net_device 
*netdev,
        struct nes_vnic *nesvnic = netdev_priv(netdev);
 
        et_pauseparam->autoneg = 0;
-       et_pauseparam->rx_pause = 
(nesvnic->nesdev->disable_rx_flow_control==0)?1:0;
-       et_pauseparam->tx_pause = 
(nesvnic->nesdev->disable_tx_flow_control==0)?1:0;
+       et_pauseparam->rx_pause = (nesvnic->nesdev->disable_rx_flow_control == 
0) ? 1:0;
+       et_pauseparam->tx_pause = (nesvnic->nesdev->disable_tx_flow_control == 
0) ? 1:0;
 }
 
 
@@ -1144,14 +1355,14 @@ static int nes_netdev_set_pauseparam(struct net_device 
*netdev,
                /* TODO: should return unsupported */
                return 0;
        }
-       if ((et_pauseparam->tx_pause==1) && 
(nesdev->disable_tx_flow_control==1)) {
+       if ((et_pauseparam->tx_pause == 1) && (nesdev->disable_tx_flow_control 
== 1)) {
                u32temp = nes_read_indexed(nesdev,
                                NES_IDX_MAC_TX_CONFIG + 
(nesdev->mac_index*0x200));
                u32temp |= NES_IDX_MAC_TX_CONFIG_ENABLE_PAUSE;
                nes_write_indexed(nesdev,
                                NES_IDX_MAC_TX_CONFIG_ENABLE_PAUSE + 
(nesdev->mac_index*0x200), u32temp);
                nesdev->disable_tx_flow_control = 0;
-       } else if ((et_pauseparam->tx_pause==0) && 
(nesdev->disable_tx_flow_control==0)) {
+       } else if ((et_pauseparam->tx_pause == 0) && 
(nesdev->disable_tx_flow_control == 0)) {
                u32temp = nes_read_indexed(nesdev,
                                NES_IDX_MAC_TX_CONFIG + 
(nesdev->mac_index*0x200));
                u32temp &= ~NES_IDX_MAC_TX_CONFIG_ENABLE_PAUSE;
@@ -1159,14 +1370,14 @@ static int nes_netdev_set_pauseparam(struct net_device 
*netdev,
                                NES_IDX_MAC_TX_CONFIG_ENABLE_PAUSE + 
(nesdev->mac_index*0x200), u32temp);
                nesdev->disable_tx_flow_control = 1;
        }
-       if ((et_pauseparam->rx_pause==1) && 
(nesdev->disable_rx_flow_control==1)) {
+       if ((et_pauseparam->rx_pause == 1) && (nesdev->disable_rx_flow_control 
== 1)) {
                u32temp = nes_read_indexed(nesdev,
                                NES_IDX_MPP_DEBUG + (nesdev->mac_index*0x40));
                u32temp &= ~NES_IDX_MPP_DEBUG_PORT_DISABLE_PAUSE;
                nes_write_indexed(nesdev,
                                NES_IDX_MPP_DEBUG + (nesdev->mac_index*0x40), 
u32temp);
                nesdev->disable_rx_flow_control = 0;
-       } else if ((et_pauseparam->rx_pause==0) && 
(nesdev->disable_rx_flow_control==0)) {
+       } else if ((et_pauseparam->rx_pause == 0) && 
(nesdev->disable_rx_flow_control == 0)) {
                u32temp = nes_read_indexed(nesdev,
                                NES_IDX_MPP_DEBUG + (nesdev->mac_index*0x40));
                u32temp |= NES_IDX_MPP_DEBUG_PORT_DISABLE_PAUSE;
@@ -1190,6 +1401,7 @@ static int nes_netdev_get_settings(struct net_device 
*netdev, struct ethtool_cmd
        u16 phy_data;
 
        et_cmd->duplex = DUPLEX_FULL;
+       et_cmd->port = PORT_MII;
        if (nesadapter->OneG_Mode) {
                et_cmd->supported = SUPPORTED_1000baseT_Full|SUPPORTED_Autoneg;
                et_cmd->advertising = 
ADVERTISED_1000baseT_Full|ADVERTISED_Autoneg;
@@ -1204,14 +1416,21 @@ static int nes_netdev_get_settings(struct net_device 
*netdev, struct ethtool_cmd
                et_cmd->transceiver = XCVR_EXTERNAL;
                et_cmd->phy_address = nesadapter->phy_index[nesdev->mac_index];
        } else {
-               et_cmd->supported = SUPPORTED_10000baseT_Full;
-               et_cmd->advertising = ADVERTISED_10000baseT_Full;
+               if (nesadapter->phy_type[nesvnic->logical_port] == 
NES_PHY_TYPE_IRIS) {
+                       et_cmd->transceiver = XCVR_EXTERNAL;
+                       et_cmd->port = PORT_FIBRE;
+                       et_cmd->supported = SUPPORTED_FIBRE;
+                       et_cmd->advertising = ADVERTISED_FIBRE;
+                       et_cmd->phy_address = 
nesadapter->phy_index[nesdev->mac_index];
+               } else {
+                       et_cmd->transceiver = XCVR_INTERNAL;
+                       et_cmd->supported = SUPPORTED_10000baseT_Full;
+                       et_cmd->advertising = ADVERTISED_10000baseT_Full;
+                       et_cmd->phy_address = nesdev->mac_index;
+               }
                et_cmd->speed = SPEED_10000;
                et_cmd->autoneg = AUTONEG_DISABLE;
-               et_cmd->transceiver = XCVR_INTERNAL;
-               et_cmd->phy_address = nesdev->mac_index;
        }
-       et_cmd->port = PORT_MII;
        et_cmd->maxtxpkt = 511;
        et_cmd->maxrxpkt = 511;
        return 0;
@@ -1246,25 +1465,6 @@ static int nes_netdev_set_settings(struct net_device 
*netdev, struct ethtool_cmd
 }
 
 
-/**
- * nes_netdev_get_msglevel
- */
-static u32 nes_netdev_get_msglevel(struct net_device *netdev)
-{
-       return nes_debug_level;
-}
-
-
-/**
- * nes_netdev_set_msglevel
- */
-static void nes_netdev_set_msglevel(struct net_device *netdev, u32 level)
-{
-       nes_debug(NES_DBG_NETDEV, "Setting message level to: %u\n", level);
-       nes_debug_level = level;
-}
-
-
 static struct ethtool_ops nes_ethtool_ops = {
        .get_link = ethtool_op_get_link,
        .get_settings = nes_netdev_get_settings,
@@ -1280,8 +1480,6 @@ static struct ethtool_ops nes_ethtool_ops = {
        .set_coalesce = nes_netdev_set_coalesce,
        .get_pauseparam = nes_netdev_get_pauseparam,
        .set_pauseparam = nes_netdev_set_pauseparam,
-       .get_msglevel = nes_netdev_get_msglevel,
-       .set_msglevel = nes_netdev_set_msglevel,
        .set_tx_csum = ethtool_op_set_tx_csum,
        .set_rx_csum = nes_netdev_set_rx_csum,
        .set_sg = ethtool_op_set_sg,
@@ -1324,6 +1522,8 @@ struct net_device *nes_netdev_init(struct nes_device 
*nesdev,
        struct net_device *netdev;
        struct nic_qp_map *curr_qp_map;
        u32 u32temp;
+       u16 phy_data;
+       u16 temp_phy_data;
 
        netdev = alloc_etherdev(sizeof(struct nes_vnic));
        if (!netdev) {
@@ -1331,7 +1531,7 @@ struct net_device *nes_netdev_init(struct nes_device 
*nesdev,
                return NULL;
        }
 
-       nes_debug(NES_DBG_INIT, "netdev = %p.\n", netdev);
+       nes_debug(NES_DBG_INIT, "netdev = %p, %s\n", netdev, netdev->name);
 
        SET_NETDEV_DEV(netdev, &nesdev->pcidev->dev);
 
@@ -1341,6 +1541,9 @@ struct net_device *nes_netdev_init(struct nes_device 
*nesdev,
        netdev->get_stats = nes_netdev_get_stats;
        netdev->tx_timeout = nes_netdev_tx_timeout;
        netdev->set_mac_address = nes_netdev_set_mac_address;
+#ifdef HAVE_MULTICAST
+       netdev->set_multicast_list = nes_netdev_set_multicast_list;
+#endif
        netdev->change_mtu = nes_netdev_change_mtu;
        netdev->watchdog_timeo = NES_TX_TIMEOUT;
        netdev->irq = nesdev->pcidev->irq;
@@ -1389,16 +1592,17 @@ struct net_device *nes_netdev_init(struct nes_device 
*nesdev,
        netdev->dev_addr[3] = (u8)(u64temp>>16);
        netdev->dev_addr[4] = (u8)(u64temp>>8);
        netdev->dev_addr[5] = (u8)u64temp;
+       memcpy(netdev->perm_addr, netdev->dev_addr, 6);
 
        if ((nesvnic->logical_port < 2) || (nesdev->nesadapter->hw_rev != 
NE020_REV)) {
 #ifdef NETIF_F_TSO
-               netdev->features |= NETIF_F_TSO | NETIF_F_SG | NETIF_F_FRAGLIST 
| NETIF_F_IP_CSUM;
+               netdev->features |= NETIF_F_TSO | NETIF_F_SG | NETIF_F_IP_CSUM;
 #endif
 #ifdef NETIF_F_GSO
                netdev->features |= NETIF_F_GSO | NETIF_F_TSO | NETIF_F_SG | 
NETIF_F_IP_CSUM;
 #endif
        } else {
-               netdev->features |= NETIF_F_SG | NETIF_F_FRAGLIST | 
NETIF_F_IP_CSUM;
+               netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
        }
 
        nes_debug(NES_DBG_INIT, "nesvnic = %p, reported features = 0x%lX, QPid 
= %d,"
@@ -1431,11 +1635,8 @@ struct net_device *nes_netdev_init(struct nes_device 
*nesdev,
        }
        nesvnic->next_qp_nic_index = 0;
 
-       if (0 == nesdev->netdev_count) {
-               if (rdma_enabled == 0) {
-                       rdma_enabled = 1;
-                       nesvnic->rdma_enabled = 1;
-               }
+       if (nesdev->netdev_count == 0) {
+               nesvnic->rdma_enabled = 1;
        } else {
                nesvnic->rdma_enabled = 0;
        }
@@ -1447,7 +1648,7 @@ struct net_device *nes_netdev_init(struct nes_device 
*nesdev,
                        nesvnic, nesdev->mac_index);
        list_add_tail(&nesvnic->list, 
&nesdev->nesadapter->nesvnic_list[nesdev->mac_index]);
 
-       if ((0 == nesdev->netdev_count) &&
+       if ((nesdev->netdev_count == 0) &&
                        (PCI_FUNC(nesdev->pcidev->devfn) == nesdev->mac_index)) 
{
                nes_debug(NES_DBG_INIT, "Setting up PHY interrupt mask. Using 
register index 0x%04X\n",
                                
NES_IDX_PHY_PCS_CONTROL_STATUS0+(0x200*(nesvnic->logical_port&1)));
@@ -1458,9 +1659,32 @@ struct net_device *nes_netdev_init(struct nes_device 
*nesdev,
                                (0x200*(nesvnic->logical_port&1)), u32temp);
                u32temp = nes_read_indexed(nesdev, 
NES_IDX_PHY_PCS_CONTROL_STATUS0 +
                                (0x200*(nesvnic->logical_port&1)) );
-               if (0x0f0f0000 == (u32temp&0x0f1f0000)) {
-                       nes_debug(NES_DBG_INIT, "The Link is UP!!.\n");
-                       nesvnic->linkup = 1;
+               if ((u32temp&0x0f1f0000) == 0x0f0f0000) {
+                       if (nesdev->nesadapter->phy_type[nesvnic->logical_port] 
== NES_PHY_TYPE_IRIS) {
+                               nes_read_10G_phy_reg(nesdev, 1,
+                                               
nesdev->nesadapter->phy_index[nesvnic->logical_port]);
+                               temp_phy_data = (u16)nes_read_indexed(nesdev,
+                                                                       
NES_IDX_MAC_MDIO_CONTROL);
+                               u32temp = 20;
+                               do {
+                                       nes_read_10G_phy_reg(nesdev, 1,
+                                                       
nesdev->nesadapter->phy_index[nesvnic->logical_port]);
+                                       phy_data = (u16)nes_read_indexed(nesdev,
+                                                                       
NES_IDX_MAC_MDIO_CONTROL);
+                                       if ((phy_data == temp_phy_data) || 
(!(--u32temp)))
+                                               break;
+                                       temp_phy_data = phy_data;
+                               } while (1);
+                               if (phy_data & 4) {
+                                       nes_debug(NES_DBG_INIT, "The Link is 
UP!!.\n");
+                                       nesvnic->linkup = 1;
+                               } else {
+                                       nes_debug(NES_DBG_INIT, "The Link is 
DOWN!!.\n");
+                               }
+                       } else {
+                               nes_debug(NES_DBG_INIT, "The Link is UP!!.\n");
+                               nesvnic->linkup = 1;
+                       }
                }
                nes_debug(NES_DBG_INIT, "Setting up MAC interrupt mask.\n");
                /* clear the MAC interrupt status, assumes direct logical to 
physical mapping */
@@ -1513,4 +1737,3 @@ int nes_nic_cm_xmit(struct sk_buff *skb, struct 
net_device *netdev)
 
        return ret;
 }
-
_______________________________________________
general mailing list
[email protected]
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to