From f85a384d676ca26cdd1d8fd9f33b105a1d933338 Mon Sep 17 00:00:00 2001 From: harti Date: Thu, 31 Jul 2003 14:52:44 +0000 Subject: Implement a traffic shaping option for the PCA200 for CBR channels. This is controlled by a per-adapter sysctl hw.atm.hfaX.shape. When set to 0, no shaping occures. When set to 1 at most 1 channel is shaped. When set to 2 all CBR channels are shaped. Note, that the latter may actually not work, because of the adapter supporting the shaping of only one PDU at the same time. --- sys/dev/hfa/fore_output.c | 2 +- sys/dev/hfa/fore_var.h | 11 +++ sys/dev/hfa/fore_vcm.c | 188 ++++++++++++++++++++++++++++++++++++++++++++++ sys/dev/hfa/hfa_freebsd.c | 43 +++++++++++ sys/dev/hfa/hfa_freebsd.h | 4 + 5 files changed, 247 insertions(+), 1 deletion(-) (limited to 'sys/dev/hfa') 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) -- cgit v1.1