[PATCH] sethdlc/ioctl changes for T1

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I initially sent this directly to Krzysztof Halasa <khc@pm.waw.pl>, but it
bounced.  Krzysztof, if you're out there, please let me know.  (I'm also
making good progress on making pppd control HDLC PPP, so expect another
patch in the next week or two.)

BTW, these patches are made from ppc linux 2.4.21-pre4 and sethdlc 1.14.

-- 
Dan Eble <dane@aiinet.com>  _____  .
                           |  _  |/|
Applied Innovation Inc.    | |_| | |
http://www.aiinet.com/     |__/|_|_|

---------- Forwarded message ----------
Date: Tue, 27 May 2003 08:45:03 -0400 (EDT)
From: Dan Eble <dane@aiinet.com>
Subject: sethdlc/ioctl changes for T1

As we discussed in April, I have changed the te1_settings structure to
contain only channel-specific parameters (clock rate and slot map),
leaving it up to the framer driver to set framer-wide parameters.  (In my
case, it is done through /proc files.)

The sethdlc command has been modified accordingly.  I have only tested 
it with T1 links.  It was a bit hairy to separate te1_settings from 
sync_serial_settings in sethdlc, but I think I got it right.
--- ioctl.h.old	2003-05-27 08:33:25.000000000 -0400
+++ ioctl.h	2003-04-25 15:35:50.000000000 -0400
@@ -7,11 +7,13 @@
 	unsigned short loopback;
 } sync_serial_settings;          /* V.35, V.24, X.21 */
 
+/** te1_settings contains options for channels (fractions) of a T1 or
+ * E1 line.  Settings that apply to the line as a whole (e.g. encoding,
+ * build-out, loopback) are configured in a driver-specific way.
+ */
 typedef struct { 
-	unsigned int clock_rate; /* bits per second */
-	unsigned int clock_type; /* internal, external, TX-internal etc. */
-	unsigned short loopback;
-	unsigned int slot_map;
+	unsigned int clock_rate; /* 64000 or 56000 */
+	unsigned int slot_map;   /* LSB = lowest-numbered channel */
 } te1_settings;                  /* T1, E1 */
 
 typedef struct {
--- sethdlc.c.old	2003-05-27 08:41:48.000000000 -0400
+++ sethdlc.c	2003-04-25 16:08:09.000000000 -0400
@@ -121,8 +121,15 @@
 	if (argc < 1)
 		error("Missing parameter\n");
 
+	/* Hm, what about strtol()?  It will parse base 8, 10, or 16. */
+	if ((argv[0][0] == '0') &&
+	    ((argv[0][1] == 'x') || (argv[0][1] == 'X'))) {
+		if (sscanf(argv[0], "%x%c", value, &test) != 1)
+			error("Invalid parameter: %s\n", argv[0]);
+	} else {
 	if (sscanf(argv[0], "%u%c", value, &test) != 1)
 		error("Invalid parameter: %s\n", argv[0]);
+	}
 
 	if ((*value > maximum) || (*value < minimum))
 		error("Parameter out of range [%u - %u]: %u\n",
@@ -178,57 +185,108 @@
 			  { NULL, 0 }};
 
 
-static void set_iface(void)
+
+static void set_iface_sync(void)
 {
 	int orig_argc = argc;
-	te1_settings te1;
+	sync_serial_settings sync;
 
-	memset(&te1, 0, sizeof(te1));
-	req.ifr_settings.type = IF_IFACE_SYNC_SERIAL;
+	memset(&sync, 0, sizeof(sync));
 
 	while (argc > 0) {
-		if (req.ifr_settings.type == IF_IFACE_SYNC_SERIAL)
-			if (!checktab(ifaces, &req.ifr_settings.type))
-				continue;
-
-		if (!te1.clock_type)
+		if (!sync.clock_type)
 			if (!checkkey("clock")) {
-				if (!checktab(clocks, &te1.clock_type))
+				if (!checktab(clocks, &sync.clock_type))
 					continue;
 				error("Invalid clock type\n");
 			}
 
-		if (!te1.clock_rate &&
-		    (te1.clock_type == CLOCK_INT ||
-		     te1.clock_type == CLOCK_TXINT))
-			if (!match("rate", &te1.clock_rate, 1, 0xFFFFFFFF))
+		if (!sync.clock_rate &&
+		    (sync.clock_type == CLOCK_INT ||
+		     sync.clock_type == CLOCK_TXINT))
+			if (!match("rate", &sync.clock_rate, 1, 0xFFFFFFFF))
 				continue;
-		if (!te1.loopback) {
+		if (!sync.loopback) {
 			if (!checkkey("loopback") ||
 			    !checkkey("lb")) {
-				te1.loopback = 1;
+				sync.loopback = 1;
 				continue;
 			}
 		}
-		/* slotmap goes here */
 
 		if (orig_argc == argc)
 			return;	/* not an iface definition */
 		error("Invalid parameter: %s\n", argv[0]);
 	}
 
-	if (!te1.clock_rate &&
-	    (te1.clock_type == CLOCK_INT ||
-	     te1.clock_type == CLOCK_TXINT))
-		te1.clock_rate = 64000;
+	if (!sync.clock_rate &&
+	    (sync.clock_type == CLOCK_INT ||
+	     sync.clock_type == CLOCK_TXINT))
+		sync.clock_rate = 64000;
+
+	req.ifr_settings.ifs_ifsu.sync = &sync;
+	req.ifr_settings.size = sizeof(sync_serial_settings);
+
+	if (ioctl(sock, SIOCWANDEV, &req))
+		error("Unable to set interface information: %s\n",
+		      strerror(errno));
+
+	exit(0);
+}
+
+
+
+static void set_iface_te1(void)
+{
+	int orig_argc = argc;
+	te1_settings te1;
+
+	memset(&te1, 0, sizeof(te1));
+
+	te1.clock_rate = 64000; /* use clear channel by default */
+
+	while (argc > 0) {
+		if (!match("rate", &te1.clock_rate, 1, 0xFFFFFFFF))
+			continue;
+
+		if (!te1.slot_map) {
+			if (!match("slotmap", &te1.slot_map, 0, 0xFFFFFFFF))
+				continue;
+		}
+
+		if (orig_argc == argc)
+			return;	/* not an iface definition */
+		error("Invalid parameter: %s\n", argv[0]);
+	}
+
+	/* Rate is not the best name to use, but it works okay for now.  It
+	 * would be more accurate to use the following:
+	 *   "clearchannel"            64000 using all bits
+	 *   "idlechannel"             56000 leaving 1 of 8 bits unused
+	 *   "robbedbit"               56000 using 1 of 8 bits for signaling
+	 * I don't know enough about it yet to say whether individual timeslots
+	 * can be configured differently or whether every timeslot in the
+	 * slotmap has to be the same. */
+	if ((te1.clock_rate != 56000) &&
+	    (te1.clock_rate != 64000))
+		error("Invalid rate (use 56000 or 64000)\n");
+
+	if (req.ifr_settings.type == IF_IFACE_T1) {
+		if (te1.slot_map & ~0x00FFFFFF)
+			error("Invalid bits in T1 slotmap: 0x%0X\n",
+			      te1.slot_map & ~0x00FFFFFF);
+	}
+        else if (req.ifr_settings.type == IF_IFACE_E1) {
+		/* NB: There are additional restrictions for the E1 slotmap
+		 * when certain types of framing are used.  It is not
+		 * implemented yet. */
+		if (te1.slot_map & ~0xFFFFFFFE)
+			error("Invalid bits in E1 slotmap: 0x%0X\n",
+			      te1.slot_map & ~0xFFFFFFFE);
+	}
 
-	/* FIXME stupid hack, will remove it later */
 	req.ifr_settings.ifs_ifsu.te1 = &te1;
-	if (req.ifr_settings.type == IF_IFACE_E1 ||
-	    req.ifr_settings.type == IF_IFACE_T1)
 		req.ifr_settings.size = sizeof(te1_settings);
-	else
-		req.ifr_settings.size = sizeof(sync_serial_settings);
 
 	if (ioctl(sock, SIOCWANDEV, &req))
 		error("Unable to set interface information: %s\n",
@@ -239,6 +297,26 @@
 
 
 
+static void set_iface(void)
+{
+	/* Look for an interface type.  If absent use generic sync. */
+	if (0 != checktab(ifaces, &req.ifr_settings.type))
+		req.ifr_settings.type = IF_IFACE_SYNC_SERIAL;
+
+	switch (req.ifr_settings.type) {
+	case IF_IFACE_T1:
+	case IF_IFACE_E1:
+		set_iface_te1();
+		break;
+
+	default:
+		set_iface_sync();
+		break;
+	}
+}
+
+
+
 static void set_proto_fr(void)
 {
 	unsigned int lmi_type = 0;
@@ -468,13 +546,33 @@
 	}
 }
 
+static void show_port_te1(unsigned int type, const te1_settings *te1)
+{
+	printf(" rate %u", te1->clock_rate);
+
+	if (type == IF_IFACE_T1)
+		printf(" slotmap 0x%06X", te1->slot_map);
+	else if (type == IF_IFACE_E1)
+		printf(" slotmap 0x%08X", te1->slot_map);
+}
+
+static void show_port_sync(const sync_serial_settings *sync)
+{
+	printf("clock %s", tabstr(sync->clock_type, clocks,
+				  "type unknown"));
+
+	if (sync->clock_type == CLOCK_INT ||
+	    sync->clock_type == CLOCK_TXINT)
+		printf(" rate %u", sync->clock_rate);
 
+	if (sync->loopback)
+		printf(" loopback");
+}
 
 static void show_port(void)
 {
 	const char *s;
 	char buffer[128];
-	const te1_settings *te1 = (void*)buffer;
 	const raw_hdlc_proto *raw = (void*)buffer;
 	const cisco_proto *cisco = (void*)buffer;
 	const fr_proto *fr = (void*)buffer;
@@ -507,22 +605,12 @@
 		if (*s)
 			printf("interface %s ", s);
 
-		printf("clock %s", tabstr(te1->clock_type, clocks,
-					  "type unknown"));
-		if (te1->clock_type == CLOCK_INT ||
-		    te1->clock_type == CLOCK_TXINT)
-			printf(" rate %u", te1->clock_rate);
-
-		if (te1->loopback)
-			printf(" loopback");
+		if (req.ifr_settings.type == IF_IFACE_T1 ||
+		    req.ifr_settings.type == IF_IFACE_E1)
+			show_port_te1(req.ifr_settings.type, (void*)buffer);
+		else
+			show_port_sync((void*)buffer);
 
-		if (req.ifr_settings.type == IF_IFACE_E1 ||
-		    req.ifr_settings.type == IF_IFACE_T1) {
-			unsigned int u;
-			printf(" slotmap ");
-			for (u = te1->slot_map; u != 0; u /= 2)
-				printf("%u", u % 2);
-		}
 		printf("\n");
 	}
 
@@ -620,6 +708,7 @@
 		"PHYSICAL := v24 | v35 | x21 | e1 | t1\n"
 		"CLOCK := int [rate RATE] | ext | txint [rate RATE] | txfromrx\n"
 		"LOOPBACK := loopback | lb\n"
+		"SLOTMAP  := <integer with LSB representing timeslot 1>\n"
 		"\n"
 		"PROTOCOL := hdlc [ENCODING] [PARITY] |\n"
 		"            hdlc-eth [ENCODING] [PARITY] |\n"

[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux 802.1Q VLAN]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Git]     [Bugtraq]     [Yosemite News and Information]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux PCI]     [Linux Admin]     [Samba]

  Powered by Linux