netxen: fix promisc mode, mtu setting

For NX3031, multicast filtering, promisc mode, and max frame size
setting is handled by firmware, driver needs to send request to
enable/disable it.

For old chip revisions / firmware, driver still sets it directly.

Added function pointer to set mtu according to chip revision.

Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index d0c6935..4259f3f 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -285,14 +285,7 @@
 #define ADDR_IN_RANGE(addr, low, high)	\
 	(((addr) <= (high)) && ((addr) >= (low)))
 
-#define NETXEN_MAX_MTU		8000 + NETXEN_ENET_HEADER_SIZE + NETXEN_ETH_FCS_SIZE
-#define NETXEN_MIN_MTU		64
-#define NETXEN_ETH_FCS_SIZE     4
-#define NETXEN_ENET_HEADER_SIZE 14
 #define NETXEN_WINDOW_ONE 	0x2000000 /*CRB Window: bit 25 of CRB address */
-#define NETXEN_FIRMWARE_LEN 	((16 * 1024) / 4)
-#define NETXEN_NIU_HDRSIZE	(0x1 << 6)
-#define NETXEN_NIU_TLRSIZE	(0x1 << 5)
 
 #define NETXEN_NIC_ZERO_PAUSE_ADDR     0ULL
 #define NETXEN_NIC_UNIT_PAUSE_ADDR     0x200ULL
@@ -541,9 +534,6 @@
 	return 0;
 }
 
-#define NIC_REQUEST		0x14
-#define NETXEN_MAC_EVENT	0x1
-
 static int nx_p3_sre_macaddr_change(struct net_device *dev,
 		u8 *addr, unsigned op)
 {
@@ -553,8 +543,8 @@
 	int rv;
 
 	memset(&req, 0, sizeof(nx_nic_req_t));
-	req.qhdr |= (NIC_REQUEST << 23);
-	req.req_hdr |= NETXEN_MAC_EVENT;
+	req.qhdr |= (NX_NIC_REQUEST << 23);
+	req.req_hdr |= NX_MAC_EVENT;
 	req.req_hdr |= ((u64)adapter->portnum << 16);
 	mac_req.op = op;
 	memcpy(&mac_req.mac_addr, addr, 6);
@@ -575,31 +565,35 @@
 	nx_mac_list_t *cur, *next, *del_list, *add_list = NULL;
 	struct dev_mc_list *mc_ptr;
 	u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-
-	adapter->set_promisc(adapter, NETXEN_NIU_PROMISC_MODE);
-
-	/*
-	 * Programming mac addresses will automaticly enabling L2 filtering.
-	 * HW will replace timestamp with L2 conid when L2 filtering is
-	 * enabled. This causes problem for LSA. Do not enabling L2 filtering
-	 * until that problem is fixed.
-	 */
-	if ((netdev->flags & IFF_PROMISC) ||
-			(netdev->mc_count > adapter->max_mc_count))
-		return;
+	u32 mode = VPORT_MISS_MODE_DROP;
 
 	del_list = adapter->mac_list;
 	adapter->mac_list = NULL;
 
 	nx_p3_nic_add_mac(adapter, netdev->dev_addr, &add_list, &del_list);
+	nx_p3_nic_add_mac(adapter, bcast_addr, &add_list, &del_list);
+
+	if (netdev->flags & IFF_PROMISC) {
+		mode = VPORT_MISS_MODE_ACCEPT_ALL;
+		goto send_fw_cmd;
+	}
+
+	if ((netdev->flags & IFF_ALLMULTI) ||
+			(netdev->mc_count > adapter->max_mc_count)) {
+		mode = VPORT_MISS_MODE_ACCEPT_MULTI;
+		goto send_fw_cmd;
+	}
+
 	if (netdev->mc_count > 0) {
-		nx_p3_nic_add_mac(adapter, bcast_addr, &add_list, &del_list);
 		for (mc_ptr = netdev->mc_list; mc_ptr;
 		     mc_ptr = mc_ptr->next) {
 			nx_p3_nic_add_mac(adapter, mc_ptr->dmi_addr,
 					  &add_list, &del_list);
 		}
 	}
+
+send_fw_cmd:
+	adapter->set_promisc(adapter, mode);
 	for (cur = del_list; cur;) {
 		nx_p3_sre_macaddr_change(netdev, cur->mac_addr, NETXEN_MAC_DEL);
 		next = cur->next;
@@ -615,6 +609,21 @@
 	}
 }
 
+int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32 mode)
+{
+	nx_nic_req_t req;
+
+	memset(&req, 0, sizeof(nx_nic_req_t));
+
+	req.qhdr |= (NX_HOST_REQUEST << 23);
+	req.req_hdr |= NX_NIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE;
+	req.req_hdr |= ((u64)adapter->portnum << 16);
+	req.words[0] = cpu_to_le64(mode);
+
+	return netxen_send_cmd_descs(adapter,
+				(struct cmd_desc_type0 *)&req, 1);
+}
+
 #define	NETXEN_CONFIG_INTR_COALESCE	3
 
 /*
@@ -627,7 +636,7 @@
 
 	memset(&req, 0, sizeof(nx_nic_req_t));
 
-	req.qhdr |= (NIC_REQUEST << 23);
+	req.qhdr |= (NX_NIC_REQUEST << 23);
 	req.req_hdr |= NETXEN_CONFIG_INTR_COALESCE;
 	req.req_hdr |= ((u64)adapter->portnum << 16);
 
@@ -653,6 +662,7 @@
 {
 	struct netxen_adapter *adapter = netdev_priv(netdev);
 	int max_mtu;
+	int rc = 0;
 
 	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
 		max_mtu = P3_MAX_MTU;
@@ -666,16 +676,12 @@
 	}
 
 	if (adapter->set_mtu)
-		adapter->set_mtu(adapter, mtu);
-	netdev->mtu = mtu;
+		rc = adapter->set_mtu(adapter, mtu);
 
-	mtu += MTU_FUDGE_FACTOR;
-	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
-		nx_fw_cmd_set_mtu(adapter, mtu);
-	else if (adapter->set_mtu)
-		adapter->set_mtu(adapter, mtu);
+	if (!rc)
+		netdev->mtu = mtu;
 
-	return 0;
+	return rc;
 }
 
 int netxen_is_flash_supported(struct netxen_adapter *adapter)
@@ -2047,6 +2053,7 @@
 
 int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu)
 {
+	new_mtu += MTU_FUDGE_FACTOR;
 	netxen_nic_write_w0(adapter,
 		NETXEN_NIU_GB_MAX_FRAME_SIZE(adapter->physical_port),
 		new_mtu);
@@ -2055,7 +2062,7 @@
 
 int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu)
 {
-	new_mtu += NETXEN_NIU_HDRSIZE + NETXEN_NIU_TLRSIZE;
+	new_mtu += MTU_FUDGE_FACTOR;
 	if (adapter->physical_port == 0)
 		netxen_nic_write_w0(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE,
 				new_mtu);