[svn-commits] jbenden: branch linux/jbenden/tdmoe-variable-chunksize-and-gigabit r8629 - /l...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Mon May 17 01:19:02 CDT 2010


Author: jbenden
Date: Mon May 17 01:18:58 2010
New Revision: 8629

URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=8629
Log:
Allow for Gigabit NICs. Honor DAHDI_CHUNKSIZE (requires special clocking treatment). Handle netdevice notices a bit better. Attempt to deal with out-going Ethernet frames by way of reported device MTU size.

Modified:
    linux/team/jbenden/tdmoe-variable-chunksize-and-gigabit/drivers/dahdi/dahdi_dynamic_ethmf.c

Modified: linux/team/jbenden/tdmoe-variable-chunksize-and-gigabit/drivers/dahdi/dahdi_dynamic_ethmf.c
URL: http://svnview.digium.com/svn/dahdi/linux/team/jbenden/tdmoe-variable-chunksize-and-gigabit/drivers/dahdi/dahdi_dynamic_ethmf.c?view=diff&rev=8629&r1=8628&r2=8629
==============================================================================
--- linux/team/jbenden/tdmoe-variable-chunksize-and-gigabit/drivers/dahdi/dahdi_dynamic_ethmf.c (original)
+++ linux/team/jbenden/tdmoe-variable-chunksize-and-gigabit/drivers/dahdi/dahdi_dynamic_ethmf.c Mon May 17 01:18:58 2010
@@ -55,11 +55,16 @@
 #include <dahdi/kernel.h>
 #include <dahdi/user.h>
 
+#if DAHDI_CHUNKSIZE > 255
+# error Chunksize may not exceed 255, due to TDMoE protocol restrictions
+#endif
+
 #define ETH_P_ZTDETH			0xd00d
-#define ETHMF_MAX_PER_SPAN_GROUP	8
+#define ETHMF_MAX_PER_SPAN_GROUP	24
 #define ETHMF_MAX_GROUPS		16
+#define ETHMF_FLAG_MULTIFRAME	0x8000
 #define ETHMF_FLAG_IGNORE_CHAN0	(1 << 3)
-#define ETHMF_MAX_SPANS			4
+#define ETHMF_MAX_SPANS			24 /* allow for giga jumbo-frame, ceiling is 127 */
 
 struct ztdeth_header {
 	unsigned short subaddr;
@@ -243,17 +248,19 @@
 	struct ztdeth_header *zh;
 	unsigned int samples, channels, rbslen, flags;
 	unsigned int skip = 0;
+	unsigned short subaddr = 0;
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22)
 	zh = (struct ztdeth_header *) skb_network_header(skb);
 #else
 	zh = (struct ztdeth_header *) skb->nh.raw;
 #endif
-	if (ntohs(zh->subaddr) & 0x8000) {
-		/* got a multi-span frame */
-		num_spans = ntohs(zh->subaddr) & 0xFF;
-
-		/* Currently max of 4 spans supported */
+	subaddr = (unsigned short) ntohs(zh->subaddr);
+	if (subaddr & ETHMF_FLAG_MULTIFRAME) {
+		/* got a multi-span frame; how many spans are present? */
+		num_spans = subaddr & 0xFF;
+
+		/* Currently max of 24 spans supported */
 		if (unlikely(num_spans > ETHMF_MAX_SPANS)) {
 			kfree_skb(skb);
 			return 0;
@@ -297,7 +304,7 @@
 			else
 				rbslen = ((channels + 3) / 4) * 2;
 
-			if (unlikely(samples != 8 || channels >= 32 || channels == 0)) {
+			if (unlikely(samples != DAHDI_CHUNKSIZE || channels >= 32 || channels == 0)) {
 				ethmf_errors_inc();
 				++span_index;
 				continue;
@@ -310,7 +317,7 @@
 				 * ensure that ztdynamic doesn't get confused by this new flag
 				 */
 				if (flags & ETHMF_FLAG_IGNORE_CHAN0) {
-					skip = 8;
+					skip = DAHDI_CHUNKSIZE;
 
 					/* Remove this flag since ztdynamic may not understand it */
 					z->rcvbuf[1] = flags & ~(ETHMF_FLAG_IGNORE_CHAN0);
@@ -326,11 +333,11 @@
 
 				/* 256 == 32*8; if padding lengths change, this must be modified */
 				memcpy(z->rcvbuf + 6 + rbslen, data + 6*num_spans + 16
-					*num_spans + (256)*span_index + skip, channels
-					* 8); /* Payload */
+					*num_spans + (32 * DAHDI_CHUNKSIZE)*span_index + skip, channels
+					* DAHDI_CHUNKSIZE); /* Payload */
 
 				dahdi_dynamic_receive(span, z->rcvbuf, 6 + rbslen
-					+ channels*8);
+					+ channels*DAHDI_CHUNKSIZE);
 			} else {
 				ethmf_errors_inc();
 				printk(KERN_INFO "TDMoE span overflow detected. Span %d was dropped.", span_index);
@@ -374,7 +381,9 @@
 			}
 		}
 		rcu_read_unlock();
+		synchronize_rcu();
 		break;
+
 	case NETDEV_UP:
 		rcu_read_lock();
 		list_for_each_entry_rcu(z, &ethmf_list, list) {
@@ -387,6 +396,7 @@
 			}
 		}
 		rcu_read_unlock();
+		synchronize_rcu();
 		break;
 	}
 	return 0;
@@ -449,9 +459,9 @@
 			 * less channel
 			 */
 			if (atomic_read(&(ready_spans[index]->no_front_padding)))
-				pad[index] = (32 - chan)*8;
+				pad[index] = (32 - chan)*DAHDI_CHUNKSIZE;
 			else
-				pad[index] = (31 - chan)*8;
+				pad[index] = (31 - chan)*DAHDI_CHUNKSIZE;
 
 			if (chan == 24)
 				rbs[index] = 12;
@@ -462,9 +472,11 @@
 				rbs[spans_ready] = ((chan + 3) / 4) * 2;
 		}
 
-		/* Allocate the standard size for a 32-chan frame */
-		skb = dev_alloc_skb(1112 + dev->hard_header_len
-			+ sizeof(struct ztdeth_header) + 32);
+		/* Allocate frame buffer, at the reported MTU size; or the minimum
+		 * for a 32 channel span.
+		 */
+		skb = dev_alloc_skb(min(dev->mtu, 1112 + dev->hard_header_len + 
+			sizeof(struct ztdeth_header) + 32));
 		if (unlikely(!skb)) {
 			rcu_read_unlock();
 			ethmf_errors_inc();
@@ -494,10 +506,10 @@
 			int chan = ready_spans[index]->real_channels;
 			if (!atomic_read(&(ready_spans[index]->no_front_padding))) {
 				/* This adds an additional (padded) channel to our total */
-				memset(skb_put(skb, 8), 0xA5, 8); /* ETHMF_IGNORE_CHAN0 */
-			}
-			memcpy(skb_put(skb, chan*8), ready_spans[index]->msgbuf
-					+ (6 + rbs[index]), chan*8);
+				memset(skb_put(skb, DAHDI_CHUNKSIZE), 0xA5, DAHDI_CHUNKSIZE); /* ETHMF_IGNORE_CHAN0 */
+			}
+			memcpy(skb_put(skb, chan*DAHDI_CHUNKSIZE), ready_spans[index]->msgbuf
+					+ (6 + rbs[index]), chan*DAHDI_CHUNKSIZE);
 			if (pad[index] > 0) {
 				memset(skb_put(skb, pad[index]), 0xDD, pad[index]);
 			}
@@ -509,7 +521,7 @@
 		/* Throw on header */
 		zh = (struct ztdeth_header *)skb_push(skb,
 				sizeof(struct ztdeth_header));
-		zh->subaddr = htons((unsigned short)(0x8000 | (unsigned char)(spans_ready & 0xFF)));
+		zh->subaddr = htons((unsigned short)(ETHMF_FLAG_MULTIFRAME | (unsigned char)(spans_ready & 0xFF)));
 
 		/* Setup protocol type */
 		skb->protocol = __constant_htons(ETH_P_ZTDETH);




More information about the svn-commits mailing list