patch-2.4.15 linux/drivers/net/rrunner.c

Next file: linux/drivers/net/rrunner.h
Previous file: linux/drivers/net/pppox.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.14/linux/drivers/net/rrunner.c linux/drivers/net/rrunner.c
@@ -826,7 +826,7 @@
 		case E_RX_IDLE:
 			printk(KERN_WARNING "%s: RX data not moving\n",
 			       dev->name);
-			break;
+			goto drop;
 		case E_WATCHDOG:
 			printk(KERN_INFO "%s: The watchdog is here to see "
 			       "us\n", dev->name);
@@ -912,15 +912,43 @@
 		case E_RX_PAR_ERR:
 			printk(KERN_WARNING "%s: Receive parity error\n",
 			       dev->name);
-			break;
+			goto drop;
 		case E_RX_LLRC_ERR:
 			printk(KERN_WARNING "%s: Receive LLRC error\n",
 			       dev->name);
-			break;
+			goto drop;
 		case E_PKT_LN_ERR:
 			printk(KERN_WARNING "%s: Receive packet length "
 			       "error\n", dev->name);
-			break;
+			goto drop;
+		case E_DTA_CKSM_ERR:
+			printk(KERN_WARNING "%s: Data checksum error\n",
+			       dev->name);
+			goto drop;
+		case E_SHT_BST:
+			printk(KERN_WARNING "%s: Unexpected short burst "
+			       "error\n", dev->name);
+			goto drop;
+		case E_STATE_ERR:
+			printk(KERN_WARNING "%s: Recv. state transition"
+			       " error\n", dev->name);
+			goto drop;
+		case E_UNEXP_DATA:
+			printk(KERN_WARNING "%s: Unexpected data error\n",
+			       dev->name);
+			goto drop;
+		case E_LST_LNK_ERR:
+			printk(KERN_WARNING "%s: Link lost error\n",
+			       dev->name);
+			goto drop;
+		case E_FRM_ERR:
+			printk(KERN_WARNING "%s: Framming Error\n",
+			       dev->name);
+			goto drop;
+		case E_FLG_SYN_ERR:
+			printk(KERN_WARNING "%s: Flag sync. lost during"
+			       "packet\n", dev->name);
+			goto drop;
 		case E_RX_INV_BUF:
 			printk(KERN_ERR "%s: Invalid receive buffer "
 			       "address\n", dev->name);
@@ -942,6 +970,23 @@
 			       &regs->HostCtrl);
 			wmb();
 			break;
+		drop:
+			/* Label packet to be dropped.
+			 * Actual dropping occurs in rx
+			 * handling.
+			 *
+			 * The index of packet we get to drop is
+			 * the index of the packet following
+			 * the bad packet. -kbf
+			 */
+			{
+				u16 index = rrpriv->evt_ring[eidx].index;
+				index = (index + (RX_RING_ENTRIES - 1)) %
+					RX_RING_ENTRIES;
+				rrpriv->rx_ring[index].mode |=
+					(PACKET_BAD | PACKET_END);
+			}
+			break;
 		default:
 			printk(KERN_WARNING "%s: Unhandled event 0x%02x\n",
 			       dev->name, rrpriv->evt_ring[eidx].code);
@@ -968,6 +1013,11 @@
 		printk("len %x, mode %x\n", pkt_len,
 		       rrpriv->rx_ring[index].mode);
 #endif
+		if ( (rrpriv->rx_ring[index].mode & PACKET_BAD) == PACKET_BAD){
+			rrpriv->stats.rx_dropped++;
+			goto defer;
+		}
+
 		if (pkt_len > 0){
 			struct sk_buff *skb;
 
@@ -1046,6 +1096,15 @@
 	printk("%s: interrupt, prodidx = %i, eidx = %i\n", dev->name,
 	       prodidx, rrpriv->info->evt_ctrl.pi);
 #endif
+	/*
+	 * Order here is important.  We must handle events
+	 * before doing anything else in order to catch
+	 * such things as LLRC errors, etc -kbf
+	 */
+
+	eidx = rrpriv->info->evt_ctrl.pi;
+	if (prodidx != eidx)
+		eidx = rr_handle_event(dev, prodidx, eidx);
 
 	rxindex = rrpriv->cur_rx;
 	if (rxindex != rxlimit)
@@ -1054,15 +1113,19 @@
 	txcon = rrpriv->dirty_tx;
 	if (txcsmr != txcon) {
 		do {
-			rrpriv->stats.tx_packets++;
-			rrpriv->stats.tx_bytes +=rrpriv->tx_skbuff[txcon]->len;
-			dev_kfree_skb_irq(rrpriv->tx_skbuff[txcon]);
-
-			rrpriv->tx_skbuff[txcon] = NULL;
-			rrpriv->tx_ring[txcon].size = 0;
-			set_rraddr(&rrpriv->tx_ring[txcon].addr, 0);
-			rrpriv->tx_ring[txcon].mode = 0;
-
+			/* Due to occational firmware TX producer/consumer out
+			 * of sync. error need to check entry in ring -kbf
+			 */
+			if(rrpriv->tx_skbuff[txcon]){
+				rrpriv->stats.tx_packets++;
+				rrpriv->stats.tx_bytes +=rrpriv->tx_skbuff[txcon]->len;
+				dev_kfree_skb_irq(rrpriv->tx_skbuff[txcon]);
+
+				rrpriv->tx_skbuff[txcon] = NULL;
+				rrpriv->tx_ring[txcon].size = 0;
+				set_rraddr(&rrpriv->tx_ring[txcon].addr, 0);
+				rrpriv->tx_ring[txcon].mode = 0;
+			}
 			txcon = (txcon + 1) % TX_RING_ENTRIES;
 		} while (txcsmr != txcon);
 		wmb();
@@ -1077,10 +1140,6 @@
 		}
 	}
 
-	eidx = rrpriv->info->evt_ctrl.pi;
-	if (prodidx != eidx)
-		eidx = rr_handle_event(dev, prodidx, eidx);
-
 	eidx |= ((txcsmr << 8) | (rxlimit << 16));
 	writel(eidx, &regs->EvtCon);
 	wmb();
@@ -1238,7 +1297,7 @@
 	       index, cons);
 
 	if (rrpriv->tx_skbuff[index]){
-		len = min(0x80, rrpriv->tx_skbuff[index]->len);
+		len = min_t(int, 0x80, rrpriv->tx_skbuff[index]->len);
 		printk("skbuff for index %i is valid - dumping data (0x%x bytes - DMA len 0x%x)\n", index, len, rrpriv->tx_ring[index].size);
 		for (i = 0; i < len; i++){
 			if (!(i & 7))
@@ -1249,7 +1308,7 @@
 	}
 
 	if (rrpriv->tx_skbuff[cons]){
-		len = min(0x80, rrpriv->tx_skbuff[cons]->len);
+		len = min_t(int, 0x80, rrpriv->tx_skbuff[cons]->len);
 		printk("skbuff for cons %i is valid - dumping data (0x%x bytes - skbuff len 0x%x)\n", cons, len, rrpriv->tx_skbuff[cons]->len);
 		printk("mode 0x%x, size 0x%x,\n phys %08x (virt %08lx), skbuff-addr %08lx, truesize 0x%x\n",
 		       rrpriv->tx_ring[cons].mode,

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)