summaryrefslogtreecommitdiffstats
path: root/sys/dev/hfa
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/hfa')
-rw-r--r--sys/dev/hfa/fore_output.c2
-rw-r--r--sys/dev/hfa/fore_var.h11
-rw-r--r--sys/dev/hfa/fore_vcm.c188
-rw-r--r--sys/dev/hfa/hfa_freebsd.c43
-rw-r--r--sys/dev/hfa/hfa_freebsd.h4
5 files changed, 247 insertions, 1 deletions
diff --git a/sys/dev/hfa/fore_output.c b/sys/dev/hfa/fore_output.c
index df9f0f9..7e18ee6 100644
--- a/sys/dev/hfa/fore_output.c
+++ b/sys/dev/hfa/fore_output.c
@@ -196,7 +196,7 @@ fore_output(cup, cvp, m)
xdp = hxp->hxq_descr;
xdp->xd_cell_hdr = ATM_HDR_SET(vcp->vc_vpi, vcp->vc_vci, 0, 0);
xdp->xd_spec = XDS_SET_SPEC(0, fvp->fv_aal, nsegs, pdulen);
- xdp->xd_rate = FORE_DEF_RATE;
+ xdp->xd_rate = fvp->rate;
/*
* Everything is ready to go, so officially claim the host queue
diff --git a/sys/dev/hfa/fore_var.h b/sys/dev/hfa/fore_var.h
index ba26928..f44d1c3 100644
--- a/sys/dev/hfa/fore_var.h
+++ b/sys/dev/hfa/fore_var.h
@@ -47,6 +47,7 @@
struct fore_vcc {
struct cmn_vcc fv_cmn; /* Common VCC stuff */
Fore_aal fv_aal; /* CP version of AAL */
+ uint32_t rate; /* Rate control (data/idle cell ratio) */
};
typedef struct fore_vcc Fore_vcc;
@@ -227,6 +228,10 @@ struct fore_unit {
Fore_prom *fu_promd; /* Device PROM buffer (DMA) */
struct callout_handle fu_thandle; /* Timer handle */
int fu_ft4; /* Running ForeThought 4 firmware */
+
+ /* shaping enable */
+ u_int fu_shape;
+ u_int fu_num_shaped; /* number of shaped VCCs */
};
typedef struct fore_unit Fore_unit;
@@ -253,6 +258,12 @@ typedef struct fore_unit Fore_unit;
*/
#define FUF_STATCMD 0x80 /* Statistics request in progress */
+/*
+ * Shaping values
+ */
+#define FUS_NO_SHAPING 0
+#define FUS_SHAPE_ONE 1
+#define FUS_SHAPE_ALL 2
/*
* Macros to access CP memory
diff --git a/sys/dev/hfa/fore_vcm.c b/sys/dev/hfa/fore_vcm.c
index 388578d..4a37878 100644
--- a/sys/dev/hfa/fore_vcm.c
+++ b/sys/dev/hfa/fore_vcm.c
@@ -120,6 +120,173 @@ fore_instvcc(cup, cvp)
return (0);
}
+static const u_int rate_tab[255] = {
+ 353207, /* 0 */
+ 312501, /* 1 */ 312501, /* 2 */
+ 312501, /* 3 */ 312501, /* 4 */
+ 312501, /* 5 */ 312501, /* 6 */
+ 312501, /* 7 */ 312501, /* 8 */
+ 312501, /* 9 */ 312501, /* 10 */
+ 312501, /* 11 */ 312501, /* 12 */
+ 312501, /* 13 */ 312501, /* 14 */
+ 312501, /* 15 */ 312501, /* 16 */
+ 312501, /* 17 */ 284091, /* 18 */
+ 284091, /* 19 */ 284091, /* 20 */
+ 284091, /* 21 */ 284091, /* 22 */
+ 284091, /* 23 */ 284091, /* 24 */
+ 284091, /* 25 */ 284091, /* 26 */
+ 284091, /* 27 */ 284091, /* 28 */
+ 284091, /* 29 */ 284091, /* 30 */
+ 284091, /* 31 */ 284091, /* 32 */
+ 284091, /* 33 */ 284091, /* 34 */
+ 284091, /* 35 */ 284091, /* 36 */
+ 284091, /* 37 */ 284091, /* 38 */
+ 260417, /* 39 */ 260417, /* 40 */
+ 260417, /* 41 */ 260417, /* 42 */
+ 260417, /* 43 */ 260417, /* 44 */
+ 260417, /* 45 */ 260417, /* 46 */
+ 260417, /* 47 */ 260417, /* 48 */
+ 260417, /* 49 */ 260417, /* 50 */
+ 260417, /* 51 */ 260417, /* 52 */
+ 260417, /* 53 */ 260417, /* 54 */
+ 260417, /* 55 */ 240385, /* 56 */
+ 240385, /* 57 */ 240385, /* 58 */
+ 240385, /* 59 */ 240385, /* 60 */
+ 240385, /* 61 */ 240385, /* 62 */
+ 240385, /* 63 */ 240385, /* 64 */
+ 240385, /* 65 */ 240385, /* 66 */
+ 240385, /* 67 */ 240385, /* 68 */
+ 240385, /* 69 */ 240385, /* 70 */
+ 223215, /* 71 */ 223215, /* 72 */
+ 223215, /* 73 */ 223215, /* 74 */
+ 223215, /* 75 */ 223215, /* 76 */
+ 223215, /* 77 */ 223215, /* 78 */
+ 223215, /* 79 */ 223215, /* 80 */
+ 223215, /* 81 */ 223215, /* 82 */
+ 223215, /* 83 */ 208334, /* 84 */
+ 208334, /* 85 */ 208334, /* 86 */
+ 208334, /* 87 */ 208334, /* 88 */
+ 208334, /* 89 */ 208334, /* 90 */
+ 208334, /* 91 */ 208334, /* 92 */
+ 208334, /* 93 */ 208334, /* 94 */
+ 195313, /* 95 */ 195313, /* 96 */
+ 195313, /* 97 */ 195313, /* 98 */
+ 195313, /* 101 */ 195313, /* 102 */
+ 195313, /* 103 */ 183824, /* 104 */
+ 183824, /* 105 */ 183824, /* 106 */
+ 183824, /* 107 */ 183824, /* 108 */
+ 183824, /* 109 */ 183824, /* 110 */
+ 183824, /* 111 */ 183824, /* 112 */
+ 173612, /* 113 */ 173612, /* 114 */
+ 173612, /* 115 */ 173612, /* 116 */
+ 173612, /* 117 */ 173612, /* 118 */
+ 173612, /* 119 */ 173612, /* 120 */
+ 164474, /* 121 */ 164474, /* 122 */
+ 164474, /* 123 */ 164474, /* 124 */
+ 164474, /* 125 */ 164474, /* 126 */
+ 164474, /* 127 */ 156250, /* 128 */
+ 156250, /* 129 */ 156250, /* 130 */
+ 156250, /* 131 */ 156250, /* 132 */
+ 156250, /* 133 */ 148810, /* 134 */
+ 148810, /* 135 */ 148810, /* 136 */
+ 148810, /* 137 */ 148810, /* 138 */
+ 148810, /* 139 */ 142046, /* 140 */
+ 142046, /* 141 */ 142046, /* 142 */
+ 142046, /* 143 */ 142046, /* 144 */
+ 135870, /* 145 */ 135870, /* 146 */
+ 135870, /* 147 */ 135870, /* 148 */
+ 130209, /* 149 */ 130209, /* 150 */
+ 130209, /* 151 */ 130209, /* 152 */
+ 130209, /* 153 */ 125000, /* 154 */
+ 125000, /* 155 */ 125000, /* 156 */
+ 125000, /* 157 */ 120193, /* 158 */
+ 120193, /* 159 */ 120193, /* 160 */
+ 115741, /* 161 */ 115741, /* 162 */
+ 115741, /* 163 */ 115741, /* 164 */
+ 111608, /* 165 */ 111608, /* 166 */
+ 111608, /* 167 */ 107759, /* 168 */
+ 107759, /* 169 */ 107759, /* 170 */
+ 104167, /* 171 */ 104167, /* 172 */
+ 104167, /* 173 */ 100807, /* 174 */
+ 100807, /* 175 */ 97657, /* 176 */
+ 97657, /* 177 */ 97657, /* 178 */
+ 94697, /* 179 */ 94697, /* 180 */
+ 91912, /* 181 */ 91912, /* 182 */
+ 89286, /* 183 */ 89286, /* 184 */
+ 86806, /* 185 */ 86806, /* 186 */
+ 84460, /* 187 */ 84460, /* 188 */
+ 82237, /* 189 */ 82237, /* 190 */
+ 80129, /* 191 */ 78125, /* 192 */
+ 78126, /* 193 */ 76220, /* 194 */
+ 74405, /* 195 */ 74405, /* 196 */
+ 72675, /* 197 */ 71023, /* 198 */
+ 69445, /* 199 */ 69445, /* 200 */
+ 67935, /* 201 */ 66490, /* 202 */
+ 65105, /* 203 */ 63776, /* 204 */
+ 62500, /* 205 */ 61275, /* 206 */
+ 60097, /* 207 */ 58963, /* 208 */
+ 57871, /* 209 */ 56819, /* 210 */
+ 54825, /* 211 */ 53880, /* 212 */
+ 52967, /* 213 */ 51230, /* 214 */
+ 50404, /* 215 */ 48829, /* 216 */
+ 47349, /* 217 */ 46642, /* 218 */
+ 45290, /* 219 */ 44015, /* 220 */
+ 42809, /* 221 */ 41119, /* 222 */
+ 40065, /* 223 */ 39063, /* 224 */
+ 37651, /* 225 */ 36338, /* 226 */
+ 35113, /* 227 */ 33968, /* 228 */
+ 32553, /* 229 */ 31250, /* 230 */
+ 30049, /* 231 */ 28936, /* 232 */
+ 27655, /* 233 */ 26261, /* 234 */
+ 25000, /* 235 */ 23855, /* 236 */
+ 22645, /* 237 */ 21259, /* 238 */
+ 20033, /* 239 */ 18826, /* 240 */
+ 17557, /* 241 */ 16277, /* 242 */
+ 15025, /* 243 */ 13767, /* 244 */
+ 12551, /* 245 */ 11282, /* 246 */
+ 10017, /* 247 */ 8779, /* 248 */
+ 7531, /* 249 */ 6263, /* 250 */
+ 5017, /* 251 */ 3761, /* 252 */
+ 2509, /* 253 */ 1254, /* 254 */
+};
+
+/*
+ * Find the best match of the high part of the Rate Control Information
+ *
+ * This function is called when a VC is opened in order to help
+ * in converting Fore's rate to PCR.
+ * The Fore's Rate Control Information is encoded as 32-bit field
+ * comprised of two 16-bit subfields.
+ *
+ * Arguments:
+ * *pcr Peak Cell Rate, will be updated with actual value
+ *
+ * Returns:
+ * descr the rate descriptor
+ *
+ */
+static uint32_t
+pcr2rate(int32_t *pcr)
+{
+ u_int i;
+
+ if (*pcr >= rate_tab[0]) {
+ /* special case link rate */
+ *pcr = rate_tab[0];
+ return (0);
+ }
+
+ for (i = 0; i < sizeof(rate_tab) / sizeof(rate_tab[0]); i++)
+ if (*pcr >= rate_tab[i])
+ break;
+ if (i == sizeof(rate_tab) / sizeof(rate_tab[0])) {
+ /* smaller than smallest */
+ i--;
+ }
+ /* update with the actual value */
+ *pcr = rate_tab[i];
+ return ((255 - i) << 16) | i;
+}
/*
* Open a VCC
@@ -167,6 +334,24 @@ fore_openvcc(cup, cvp)
}
/*
+ * Compute the PCR (but only for outgoing VCCs)
+ */
+ fvp->rate = FORE_DEF_RATE;
+ if ((vcp->vc_type & VCC_OUT) && cvp->cv_connvc) {
+ Atm_attributes *attr = &cvp->cv_connvc->cvc_attr;
+
+ if (attr && attr->traffic.v.forward.PCR_all_traffic > 0 &&
+ attr->traffic.v.forward.PCR_all_traffic < rate_tab[0] &&
+ (fup->fu_shape == FUS_SHAPE_ALL ||
+ (fup->fu_shape == FUS_SHAPE_ONE &&
+ fup->fu_num_shaped == 0))) {
+ fvp->rate = pcr2rate(&attr->traffic.v.forward.
+ PCR_all_traffic);
+ fup->fu_num_shaped++;
+ }
+ }
+
+ /*
* Only need to tell the CP about incoming VCCs
*/
if ((vcp->vc_type & VCC_IN) == 0) {
@@ -336,6 +521,9 @@ fore_closevcc(cup, cvp)
if (fvp->fv_state == CVS_ACTIVE)
fup->fu_open_vcc--;
+ if (fvp->rate != 0)
+ fup->fu_num_shaped--;
+
DEVICE_UNLOCK((Cmn_unit *)fup);
return (err);
diff --git a/sys/dev/hfa/hfa_freebsd.c b/sys/dev/hfa/hfa_freebsd.c
index d535336..94b5ff0 100644
--- a/sys/dev/hfa/hfa_freebsd.c
+++ b/sys/dev/hfa/hfa_freebsd.c
@@ -97,6 +97,36 @@ devclass_t hfa_devclass;
static int hfa_modevent(module_t, int, void *);
+SYSCTL_DECL(_hw_atm);
+
+/*
+ * Sysctl handler for the traffic shaping option
+ */
+static int
+hfa_sysctl_shape(SYSCTL_HANDLER_ARGS)
+{
+ struct hfa_softc *sc = arg1;
+ int error;
+ u_int new;
+
+ error = SYSCTL_OUT(req, &sc->fup.fu_shape , sizeof(sc->fup.fu_shape));
+ if (error != 0 || req->newptr == NULL) {
+ return (error);
+ }
+
+ error = SYSCTL_IN(req, &new, sizeof(new));
+ if (error != 0) {
+ return (error);
+ }
+
+ if (new > FUS_SHAPE_ALL) {
+ return (EINVAL);
+ }
+
+ sc->fup.fu_shape = new;
+ return (0);
+}
+
int
hfa_alloc (device_t dev)
{
@@ -122,6 +152,19 @@ hfa_alloc (device_t dev)
goto fail;
}
+ /*
+ * Make the sysctl tree
+ */
+ if ((sc->sysctl_tree = SYSCTL_ADD_NODE(&sc->sysctl_ctx,
+ SYSCTL_STATIC_CHILDREN(_hw_atm), OID_AUTO,
+ device_get_nameunit(dev), CTLFLAG_RW, 0, "")) == NULL)
+ goto fail;
+
+ if (SYSCTL_ADD_PROC(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
+ OID_AUTO, "shape", CTLFLAG_RW | CTLTYPE_UINT, sc, 0,
+ hfa_sysctl_shape, "IU", "traffic shaping") == NULL)
+ goto fail;
+
mtx_init(&sc->mtx, device_get_nameunit(dev), "Interrupt lock", MTX_DEF|MTX_RECURSE);
fail:
diff --git a/sys/dev/hfa/hfa_freebsd.h b/sys/dev/hfa/hfa_freebsd.h
index a123847..7540016 100644
--- a/sys/dev/hfa/hfa_freebsd.h
+++ b/sys/dev/hfa/hfa_freebsd.h
@@ -40,6 +40,10 @@ struct hfa_softc {
struct mtx mtx;
Fore_unit fup;
+
+ /* sysctl support */
+ struct sysctl_ctx_list sysctl_ctx;
+ struct sysctl_oid * sysctl_tree;
};
#define HFA_LOCK(_sc) mtx_lock(&(_sc)->mtx)
OpenPOWER on IntegriCloud