1 /* Copyright (C) 2009-2013 B.A.T.M.A.N. contributors:
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of version 2 of the GNU General Public
7 * License as published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 #include "gateway_common.h"
22 #include "gateway_client.h"
24 /* calculates the gateway class from kbit */
25 static void batadv_kbit_to_gw_bandwidth(int down
, int up
, long *gw_srv_class
)
27 int mdown
= 0, tdown
, tup
, difference
;
31 difference
= 0x0FFFFFFF;
33 /* test all downspeeds */
34 for (sbit
= 0; sbit
< 2; sbit
++) {
35 for (part
= 0; part
< 16; part
++) {
36 tdown
= 32 * (sbit
+ 2) * (1 << part
);
38 if (abs(tdown
- down
) < difference
) {
39 *gw_srv_class
= (sbit
<< 7) + (part
<< 3);
40 difference
= abs(tdown
- down
);
46 /* test all upspeeds */
47 difference
= 0x0FFFFFFF;
49 for (part
= 0; part
< 8; part
++) {
50 tup
= ((part
+ 1) * (mdown
)) / 8;
52 if (abs(tup
- up
) < difference
) {
53 *gw_srv_class
= (*gw_srv_class
& 0xF8) | part
;
54 difference
= abs(tup
- up
);
59 /* returns the up and downspeeds in kbit, calculated from the class */
60 void batadv_gw_bandwidth_to_kbit(uint8_t gw_srv_class
, int *down
, int *up
)
62 int sbit
= (gw_srv_class
& 0x80) >> 7;
63 int dpart
= (gw_srv_class
& 0x78) >> 3;
64 int upart
= (gw_srv_class
& 0x07);
72 *down
= 32 * (sbit
+ 2) * (1 << dpart
);
73 *up
= ((upart
+ 1) * (*down
)) / 8;
76 static bool batadv_parse_gw_bandwidth(struct net_device
*net_dev
, char *buff
,
80 char *slash_ptr
, *tmp_ptr
;
83 slash_ptr
= strchr(buff
, '/');
87 if (strlen(buff
) > 4) {
88 tmp_ptr
= buff
+ strlen(buff
) - 4;
90 if (strnicmp(tmp_ptr
, "mbit", 4) == 0)
93 if ((strnicmp(tmp_ptr
, "kbit", 4) == 0) ||
98 ret
= kstrtol(buff
, 10, &ldown
);
101 "Download speed of gateway mode invalid: %s\n",
106 *down
= ldown
* multi
;
108 /* we also got some upload info */
112 if (strlen(slash_ptr
+ 1) > 4) {
113 tmp_ptr
= slash_ptr
+ 1 - 4 + strlen(slash_ptr
+ 1);
115 if (strnicmp(tmp_ptr
, "mbit", 4) == 0)
118 if ((strnicmp(tmp_ptr
, "kbit", 4) == 0) ||
123 ret
= kstrtol(slash_ptr
+ 1, 10, &lup
);
126 "Upload speed of gateway mode invalid: %s\n",
137 ssize_t
batadv_gw_bandwidth_set(struct net_device
*net_dev
, char *buff
,
140 struct batadv_priv
*bat_priv
= netdev_priv(net_dev
);
141 long gw_bandwidth_tmp
= 0;
142 int up
= 0, down
= 0;
145 ret
= batadv_parse_gw_bandwidth(net_dev
, buff
, &up
, &down
);
149 if ((!down
) || (down
< 256))
155 batadv_kbit_to_gw_bandwidth(down
, up
, &gw_bandwidth_tmp
);
157 /* the gw bandwidth we guessed above might not match the given
158 * speeds, hence we need to calculate it back to show the number
159 * that is going to be propagated
161 batadv_gw_bandwidth_to_kbit((uint8_t)gw_bandwidth_tmp
, &down
, &up
);
163 if (atomic_read(&bat_priv
->gw_bandwidth
) == gw_bandwidth_tmp
)
166 batadv_gw_deselect(bat_priv
);
168 "Changing gateway bandwidth from: '%i' to: '%ld' (propagating: %d%s/%d%s)\n",
169 atomic_read(&bat_priv
->gw_bandwidth
), gw_bandwidth_tmp
,
170 (down
> 2048 ? down
/ 1024 : down
),
171 (down
> 2048 ? "MBit" : "KBit"),
172 (up
> 2048 ? up
/ 1024 : up
),
173 (up
> 2048 ? "MBit" : "KBit"));
175 atomic_set(&bat_priv
->gw_bandwidth
, gw_bandwidth_tmp
);