3 * Fraunhofer Institute for Open Communication Systems (FhG Fokus).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * Author: Hartmut Brandt <harti@freebsd.org>
29 * This program is used to generate the different rate tables for the IDT77252
30 * driver. The generated tables are slightly different from those in the
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
36 #include <sys/types.h>
45 /* number of table entries */
46 static const u_int tsize = 256;
48 /* number of rate difference tables to create */
49 static const u_int ndtables = 16;
51 /* cell rate offset for log 0 */
52 static const double offset = 10.0;
55 * Make an internal form of the interval and be sure to round down.
63 r = fpsetround(FP_RZ);
64 id = (u_int)rint(32 * d);
68 while (id >= 32 * 32) {
72 return ((s << 10) | (id));
76 * Convert an internal interval back to a real one.
81 return ((1 << ((id >> 10) & 0xf)) * ((id & 0x3ff) / 32.0));
85 * Convert double to ATM-Forum format. Make sure to round up.
101 r = fpsetround(FP_RP);
102 id = (u_int)rint(512 * cps);
105 return ((1 << 14) | (s << 9) | (id & 0x1ff));
109 * Convert ATM forum format to double
114 return (((atmf >> 14) & 1) * (1 << ((atmf >> 9) & 0x1f)) *
115 ((512 + (atmf & 0x1ff)) / 512.0));
119 * A cell rate to the logarithmic one
122 cps2log(u_int alink, double lg)
129 return ((tsize - 1) * (1 - log(alink / lg) / log(alink / offset)));
133 * Convert log to cell rate
136 log2cps(u_int alink, u_int lg)
138 return (alink / pow(alink / offset,
139 (double)(tsize - lg - 1) / (tsize - 1)));
143 * Convert a double to an internal scaled double
153 r = fpsetround(FP_RN);
154 ifp = (u_int)rint(fp);
158 while (ifp >= 1024) {
162 return ((s << 10) | (ifp));
166 * Convert internal scaled float to double
171 return ((p & 0x3ff) * (1 << ((p >> 10) & 0xf)) / 65536.0);
175 * Generate log to rate conversion table
178 gen_log2rate(u_int alink)
180 u_int i, iinterval, atmf, n, nrm;
181 double rate, interval, xinterval, cps, xcps;
183 for (i = 0; i < 256; i++) {
184 /* get the desired rate */
185 rate = alink / pow(alink / offset,
186 (double)(tsize - i - 1) / (tsize - 1));
188 /* convert this to an interval */
189 interval = alink / rate;
191 /* make the internal form of this interval, be sure to
193 iinterval = d2interval(interval);
195 /* now convert back */
196 xinterval = interval2d(iinterval);
198 /* make a cps from this interval */
199 cps = alink / xinterval;
201 /* convert this to its ATM forum format */
202 atmf = cps2atmf(cps);
205 xcps = atmf2cps(atmf);
211 } else if (xcps < 80.0) {
214 } else if (xcps < 160.0) {
217 } else if (xcps < 320.0) {
227 printf(" 0x%08x, /* %03u: cps=%f nrm=%u int=%f */\n",
228 (atmf << 17) | (nrm << 14) | iinterval, i,
231 printf("0x%08x,\n", (atmf << 17) | (nrm << 14) |
237 * Generate rate to log conversion table
240 gen_rate2log(u_int alink)
242 u_int i, atmf, val, ilcr;
247 for (i = 0; i < 512; i++) {
248 /* make ATM Forum CPS from index */
249 atmf = (((i & 0x1f0) >> 4) << 9) |
250 ((i & 0xf) << 5) | (1 << 14);
253 cps = atmf2cps(atmf);
256 lcr = cps2log(alink, cps);
258 r = fpsetround(FP_RN);
259 ilcr = (u_int)rint(lcr);
263 val |= ilcr << (8 * (i % 4));
268 printf(" 0x%08x,\t", val);
270 printf("0x%08x,\n", val);
275 printf("/* %03u: %f -> %f */\n", i,
276 cps, log2cps(alink, ilcr));
281 * Generate one entry into the global table
284 gen_glob_entry(u_int alink, u_int fill, u_int ci, u_int ni)
287 printf(" 0x%08x, /* %2u/32 %8.6f, %6u, ci=%u, ni=%u */\n",
288 cps2atmf(alink * fill / 32.0) | (ci << 17) | (ni << 16),
289 fill, fill / 32.0, alink * fill / 32, ci, ni);
292 cps2atmf(alink * fill / 32.0) | (ci << 17) | (ni << 16));
296 * Generate global parameter table
299 gen_glob(u_int alink)
303 gen_glob_entry(alink, 32, 0, 0);
304 gen_glob_entry(alink, 16, 0, 0);
305 gen_glob_entry(alink, 8, 0, 1);
306 gen_glob_entry(alink, 4, 0, 1);
307 gen_glob_entry(alink, 2, 1, 1);
308 gen_glob_entry(alink, 1, 1, 1);
309 gen_glob_entry(alink, 0, 1, 1);
310 gen_glob_entry(alink, 0, 1, 1);
312 for (i = 0; i < tsize/2 - 8; i++) {
323 * Generate additive rate increase tables
329 double diff; /* cell rate to increase by */
334 for (t = 0; t < ndtables; t++) {
335 diff = (double)alink / (1 << t);
336 printf("/* AIR %u: diff=%f */\n", t, diff);
338 for (i = 0; i < tsize; i++) {
339 cps = log2cps(alink, i);
344 add = cps2log(alink, cps) - i;
351 printf(" 0x%08x,\t", val);
353 printf("0x%08x,\n", val);
360 printf("/* %3u: %f */\n", i, ifp2d(add));
366 * Generate rate decrease table
372 u_int t, i, f, val, diff;
374 for (t = 0; t < ndtables; t++) {
375 /* compute the log index difference */
380 d = (tsize - 1) / log(alink / offset);
381 d *= log((double)f / (f - 1));
383 printf(" /* RDF %u: 1/%u: %f */\n", t, 1 << t, d);
385 for (i = 0; i < tsize; i++) {
393 printf(" 0x%08x,\t", val);
395 printf("0x%08x,\n", val);
402 printf("/* %3u: %f */\n", i, ifp2d(diff));
408 * Create all the tables for a given link cell rate and link bit rate.
409 * The link bit rate is only used to name the table.
412 gen_tables(u_int alink, u_int mbps)
416 printf(" * Tables for %ucps and %uMbps\n", alink, mbps);
418 printf("const uint32_t patm_rtables%u[128 * (4 + 2 * %u)] = {\n",
431 main(int argc, char *argv[])
435 while ((opt = getopt(argc, argv, "v")) != -1)
444 printf(" * This file was generated by `%s'\n", argv[0]);
447 printf("#include <sys/cdefs.h>\n");
448 printf("__FBSDID(\"$FreeBSD$\");\n");
450 printf("#include <sys/types.h>\n");
452 printf("const u_int patm_rtables_size = 128 * (4 + 2 * %u);\n",
454 printf("const u_int patm_rtables_ntab = %u;\n", ndtables);
455 gen_tables(352768, 155);
456 gen_tables( 59259, 25);