[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, ðmf_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