[ewg] [PATCH 4/6] nes: Cosmetic changes; support virtual WQs and PPC

Glenn Grundstrom NetEffect glenn at lists.openfabrics.org
Wed Nov 14 14:37:25 PST 2007


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 <ggrundstrom at neteffect.com>

---
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;
 }
-



More information about the ewg mailing list