From patchwork Mon Mar 29 08:07:34 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sreenivasa Honnur X-Patchwork-Id: 48813 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 8B2F0B6EEB for ; Mon, 29 Mar 2010 19:23:29 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753470Ab0C2IXZ (ORCPT ); Mon, 29 Mar 2010 04:23:25 -0400 Received: from barracuda.s2io.com ([72.1.205.138]:48130 "EHLO barracuda.s2io.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752484Ab0C2IXV (ORCPT ); Mon, 29 Mar 2010 04:23:21 -0400 X-ASG-Debug-ID: 1269850071-55b700090000-gSecQ8 X-Barracuda-URL: http://72.1.205.138:8000/cgi-bin/mark.cgi Received: from guinness.s2io.com (localhost [127.0.0.1]) by barracuda.s2io.com (Spam & Virus Firewall) with ESMTP id 6458020B929F; Mon, 29 Mar 2010 04:07:51 -0400 (EDT) Received: from guinness.s2io.com (142-46-210.147.tel-ott.com [142.46.210.147]) by barracuda.s2io.com with ESMTP id 57mJ1x9MueYaul5E; Mon, 29 Mar 2010 04:07:51 -0400 (EDT) X-Barracuda-Envelope-From: Sreenivasa.Honnur@neterion.com X-ASG-Whitelist: Client Received: from guinness.s2io.com (localhost [127.0.0.1]) by guinness.s2io.com (8.12.6/8.12.6) with ESMTP id o2T87lmd004628; Mon, 29 Mar 2010 04:07:47 -0400 (EDT) Received: from localhost (shonnur@localhost) by guinness.s2io.com (8.12.6/8.12.6/Submit) with ESMTP id o2T87Ytw004621; Mon, 29 Mar 2010 04:07:42 -0400 (EDT) Date: Mon, 29 Mar 2010 04:07:34 -0400 (EDT) From: Sreenivasa Honnur To: davem@davemloft.net cc: netdev@vger.kernel.org, support@neterion.com X-ASG-Orig-Subj: [net-next-2.6 PATCH 1/8] vxge: Fix a receive stall due to driver being out of synch with chip. Subject: [net-next-2.6 PATCH 1/8] vxge: Fix a receive stall due to driver being out of synch with chip. Message-ID: MIME-Version: 1.0 X-Barracuda-Connect: 142-46-210.147.tel-ott.com[142.46.210.147] X-Barracuda-Start-Time: 1269850071 X-Barracuda-Virus-Scanned: by Barracuda Spam & Virus Firewall at s2io.com Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org - Fix a receive stall due to driver being out of synch with chip. In a corner case scenario the adapter's ring controller may return a RxD with transfer code of 0xC, while the host ownership bit is still set to the adapter. The driver needs to assume that this case where (host_ownership == 1 or adapter) and (transfer_code == 0xC) is valid, that is, this RxD has been returned by the receive ring controller but no frame data is associated with the rxd. - Restore the transfer code field of each newly replenished RxD to 0x0. - Code cleanup. Removed usage of magic numbers. Signed-off-by: Sreenivasa Honnur Signed-off-by: Ramkrishna Vepa --- -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff -urpN orig/drivers/net/vxge/vxge-traffic.c patch1/drivers/net/vxge/vxge-traffic.c --- orig/drivers/net/vxge/vxge-traffic.c 2010-03-19 15:42:53.000000000 +0530 +++ patch1/drivers/net/vxge/vxge-traffic.c 2010-03-19 15:54:07.000000000 +0530 @@ -878,7 +878,7 @@ void vxge_hw_ring_rxd_post_post(struct _ channel = &ring->channel; - rxdp->control_0 |= VXGE_HW_RING_RXD_LIST_OWN_ADAPTER; + rxdp->control_0 = VXGE_HW_RING_RXD_LIST_OWN_ADAPTER; if (ring->stats->common_stats.usage_cnt > 0) ring->stats->common_stats.usage_cnt--; @@ -902,7 +902,7 @@ void vxge_hw_ring_rxd_post(struct __vxge channel = &ring->channel; wmb(); - rxdp->control_0 |= VXGE_HW_RING_RXD_LIST_OWN_ADAPTER; + rxdp->control_0 = VXGE_HW_RING_RXD_LIST_OWN_ADAPTER; vxge_hw_channel_dtr_post(channel, rxdh); @@ -966,6 +966,7 @@ enum vxge_hw_status vxge_hw_ring_rxd_nex struct __vxge_hw_channel *channel; struct vxge_hw_ring_rxd_1 *rxdp; enum vxge_hw_status status = VXGE_HW_OK; + u64 control_0, own; channel = &ring->channel; @@ -977,8 +978,12 @@ enum vxge_hw_status vxge_hw_ring_rxd_nex goto exit; } + control_0 = rxdp->control_0; + own = control_0 & VXGE_HW_RING_RXD_LIST_OWN_ADAPTER; + *t_code = (u8)VXGE_HW_RING_RXD_T_CODE_GET(control_0); + /* check whether it is not the end */ - if (!(rxdp->control_0 & VXGE_HW_RING_RXD_LIST_OWN_ADAPTER)) { + if (!own || ((*t_code == VXGE_HW_RING_T_CODE_FRM_DROP) && own)) { vxge_assert(((struct vxge_hw_ring_rxd_1 *)rxdp)->host_control != 0); @@ -986,8 +991,6 @@ enum vxge_hw_status vxge_hw_ring_rxd_nex ++ring->cmpl_cnt; vxge_hw_channel_dtr_complete(channel); - *t_code = (u8)VXGE_HW_RING_RXD_T_CODE_GET(rxdp->control_0); - vxge_assert(*t_code != VXGE_HW_RING_RXD_T_CODE_UNUSED); ring->stats->common_stats.usage_cnt++; @@ -1035,12 +1038,13 @@ enum vxge_hw_status vxge_hw_ring_handle_ * such as unknown UPV6 header), Drop it !!! */ - if (t_code == 0 || t_code == 5) { + if (t_code == VXGE_HW_RING_T_CODE_OK || + t_code == VXGE_HW_RING_T_CODE_L3_PKT_ERR) { status = VXGE_HW_OK; goto exit; } - if (t_code > 0xF) { + if (t_code > VXGE_HW_RING_T_CODE_MULTI_ERR) { status = VXGE_HW_ERR_INVALID_TCODE; goto exit; } diff -urpN orig/drivers/net/vxge/vxge-traffic.h patch1/drivers/net/vxge/vxge-traffic.h --- orig/drivers/net/vxge/vxge-traffic.h 2010-03-19 15:42:53.000000000 +0530 +++ patch1/drivers/net/vxge/vxge-traffic.h 2010-03-19 15:55:56.000000000 +0530 @@ -1866,6 +1866,51 @@ struct vxge_hw_ring_rxd_info { u32 rth_hash_type; u32 rth_value; }; +/** + * enum vxge_hw_ring_tcode - Transfer codes returned by adapter + * @VXGE_HW_RING_T_CODE_OK: Transfer ok. + * @VXGE_HW_RING_T_CODE_L3_CKSUM_MISMATCH: Layer 3 checksum presentation + * configuration mismatch. + * @VXGE_HW_RING_T_CODE_L4_CKSUM_MISMATCH: Layer 4 checksum presentation + * configuration mismatch. + * @VXGE_HW_RING_T_CODE_L3_L4_CKSUM_MISMATCH: Layer 3 and Layer 4 checksum + * presentation configuration mismatch. + * @VXGE_HW_RING_T_CODE_L3_PKT_ERR: Layer 3 error unparseable packet, + * such as unknown IPv6 header. + * @VXGE_HW_RING_T_CODE_L2_FRM_ERR: Layer 2 error frame integrity + * error, such as FCS or ECC). + * @VXGE_HW_RING_T_CODE_BUF_SIZE_ERR: Buffer size error the RxD buffer( + * s) were not appropriately sized and data loss occurred. + * @VXGE_HW_RING_T_CODE_INT_ECC_ERR: Internal ECC error RxD corrupted. + * @VXGE_HW_RING_T_CODE_BENIGN_OVFLOW: Benign overflow the contents of + * Segment1 exceeded the capacity of Buffer1 and the remainder + * was placed in Buffer2. Segment2 now starts in Buffer3. + * No data loss or errors occurred. + * @VXGE_HW_RING_T_CODE_ZERO_LEN_BUFF: Buffer size 0 one of the RxDs + * assigned buffers has a size of 0 bytes. + * @VXGE_HW_RING_T_CODE_FRM_DROP: Frame dropped either due to + * VPath Reset or because of a VPIN mismatch. + * @VXGE_HW_RING_T_CODE_UNUSED: Unused + * @VXGE_HW_RING_T_CODE_MULTI_ERR: Multiple errors more than one + * transfer code condition occurred. + * + * Transfer codes returned by adapter. + */ +enum vxge_hw_ring_tcode { + VXGE_HW_RING_T_CODE_OK = 0x0, + VXGE_HW_RING_T_CODE_L3_CKSUM_MISMATCH = 0x1, + VXGE_HW_RING_T_CODE_L4_CKSUM_MISMATCH = 0x2, + VXGE_HW_RING_T_CODE_L3_L4_CKSUM_MISMATCH = 0x3, + VXGE_HW_RING_T_CODE_L3_PKT_ERR = 0x5, + VXGE_HW_RING_T_CODE_L2_FRM_ERR = 0x6, + VXGE_HW_RING_T_CODE_BUF_SIZE_ERR = 0x7, + VXGE_HW_RING_T_CODE_INT_ECC_ERR = 0x8, + VXGE_HW_RING_T_CODE_BENIGN_OVFLOW = 0x9, + VXGE_HW_RING_T_CODE_ZERO_LEN_BUFF = 0xA, + VXGE_HW_RING_T_CODE_FRM_DROP = 0xC, + VXGE_HW_RING_T_CODE_UNUSED = 0xE, + VXGE_HW_RING_T_CODE_MULTI_ERR = 0xF +}; /** * enum enum vxge_hw_ring_hash_type - RTH hash types