blob: 9e381d2a21b9e5cc3c3154643ce7327fd0614a75 [file] [log] [blame]
developer0f312e82022-11-01 12:31:52 +08001#!/usr/bin/perl
2use strict;
3use 5.010;
4
5my $indent = 0;
6
7my %chip_types = (
8 mt7615 => "mt7615",
9 mt7622 => "mt7615",
10 mt7663 => "mt7615"
11);
12
13my $chip = shift @ARGV;
14my $chip_type;
15
16$chip or usage();
17
18sub usage() {
19 print STDERR <<EOF;
20Usage: $0 <chip> [options] <file> [[options] <file>...]
21
22Options:
23 country=XX: Set country code
24 regdomain=XX: Set regdomain
25
26Multiple country codes/regdomains per file are supported
27
28EOF
29 exit(1);
30}
31
32sub convert_array($) {
33 my $array = shift;
34
35 return unless $array;
36 foreach my $i (0 .. $#{$array}) {
37 $array->[$i] = int($array->[$i] * 2);
38 }
39
40 return $array;
41}
42
43sub parse_channel($$$) {
44 my $band = shift;
45 my $channels = $band->{channels};
46
47 my $ch = shift;
48 my $line = shift;
49
50 my @data = split /\s+/, $line;
51 my $data = join(" ", @data);
52
53 my $channel = {
54 chlist => [ ],
55 data => $data,
56 mcs => [],
57 };
58
59 $channels->{$ch} = $channel;
60
61 $band->{type} eq '2' and do {
62 $channel->{"rates-cck"} = convert_array([
63 $data[0], $data[0],
64 $data[1], $data[1]
65 ]);
66 splice @data, 0, 2;
67 };
68
69 $channel->{"rates-ofdm"} = convert_array([
70 $data[0], $data[0],
71 $data[1], $data[1],
72 $data[2], $data[2],
73 $data[3], $data[4]
74 ]);
75 splice @data, 0, 5;
76
77 my @bw = ( "bw20", "bw40", "bw80", "bw160" );
78 $band->{type} eq '2' and @bw = ( "bw20", "bw40" );
79
80 foreach my $bw (@bw) {
81 push @{$channel->{"rates-mcs"}}, convert_array([
82 $data[0],
83 $data[1], $data[1],
84 $data[2], $data[2],
85 $data[3], $data[3],
86 $data[4],
87 $data[5],
88 $data[6],
89 ]);
90 splice @data, 0, 7;
91 };
92
93 @data > 0 and do {
94 $channel->{"txs-delta"} = convert_array([ reverse splice @data, 0, 3 ]);
95 delete $channel->{"txs-delta"} if join("", @{$channel->{"txs-delta"}}) =~ /^0+$/;
96 };
97}
98
99sub read_data($) {
100 my $file = shift;
101 my $band;
102 my %bands;
103
104 open FILE, "<", $file or die "Can't open file $file\n";
105 while (<FILE>) {
106 chomp;
107
108 /^Band: (2.4|5)G / and do {
109 $band = $1;
110 $band eq '2.4' and $band = "2";
111 $bands{$band} = {
112 type => $band,
113 channels => {},
114 };
115 };
116 /^Ch(\d+)\s+(.+?)\s*$/ and parse_channel($bands{$band}, $1, $2);
117 }
118 close FILE;
119
120 return \%bands;
121}
122
123sub find_matching_channel($$) {
124 my $band = shift;
125 my $channels = $band->{channels};
126
127 my $ch_idx = shift;
128 my $ch = $channels->{$ch_idx};
129
130 foreach my $cur (sort { $a <=> $b } keys %$channels) {
131 my $cur_ch;
132
133 return undef if $cur >= $ch_idx;
134
135 $cur_ch = $channels->{$cur};
136 $cur_ch->{data} eq $ch->{data} and return $cur_ch;
137 }
138}
139
140sub optimize_channels($) {
141 my $band = shift;
142 my $channels = $band->{channels};
143 my $prev;
144 my $prev_chlist;
145
146 foreach my $ch_idx (sort { $a <=> $b } keys %$channels) {
147 my $ch = $channels->{$ch_idx};
148
149 $prev and ($ch->{data} eq $prev->{data}) and do {
150 $prev_chlist->[1] = $ch_idx;
151 delete $channels->{$ch_idx};
152 next;
153 };
154
155 $prev = find_matching_channel($band, $ch_idx);
156 if ($prev) {
157 delete $channels->{$ch_idx};
158 } else {
159 $prev = $ch;
160 }
161
162 $prev_chlist = [ $ch_idx, $ch_idx ];
163 push @{$prev->{chlist}}, $prev_chlist;
164 }
165}
166
167sub add_line {
168 my $line = shift;
169 print "".("\t" x $indent).$line;
170}
171
172sub array_str($) {
173 my $a = shift;
174
175 return "<".join(" ", @$a).">";
176}
177
178sub string_array_str($) {
179 my $a = shift;
180
181 return join(", ", map { "\"$_\"" } @$a);
182}
183
184sub add_named_array($$) {
185 my $ch = shift;
186 my $type = shift;
187
188 return unless $ch->{$type};
189 add_line("$type = ".array_str($ch->{$type}).";\n");
190}
191
192sub add_named_string_array($$) {
193 my $ch = shift;
194 my $type = shift;
195
196 return unless $ch->{$type} and @{$ch->{$type}} > 0;
197 add_line("$type = ".string_array_str($ch->{$type}).";\n");
198}
199
200sub add_multi_array($$) {
201 my $name = shift;
202 my $a = shift;
203
204 add_line("$name =");
205 if (@$a > 1) {
206 my $first = 1;
207
208 print "\n";
209 $indent++;
210 foreach my $v (@$a) {
211 $first or print ",\n";
212 undef $first;
213
214 add_line(array_str($v));
215 }
216 $indent--;
217 } else {
218 print " ".array_str($a->[0]);
219 }
220 print ";\n";
221}
222
223sub print_txpower($) {
224 my $ch = shift;
225 my @data;
226
227 add_named_array($ch, "txs-delta");
228 add_named_array($ch, "rates-cck");
229 add_named_array($ch, "rates-ofdm");
230
231 my $prev;
232 foreach my $v (@{$ch->{"rates-mcs"}}) {
233 my $val = [1, @{$v}];
234
235 if ($prev and (array_str($v) eq array_str($prev))) {
236 $data[$#data]->[0]++;
237 } else {
238 push @data, $val;
239 }
240
241 $prev = $v;
242 }
243
244 add_multi_array("rates-mcs", \@data);
245};
246
247sub print_channels($) {
248 my $band = shift;
249 my $channels = $band->{channels};
250 my $r = 0;
251
252 foreach my $ch_idx (sort { $a <=> $b } keys %$channels) {
253 my $ch = $channels->{$ch_idx};
254 my $first = 1;
255
256 add_line("r$r {\n");
257 $indent++;
258
259 add_multi_array("channels", $ch->{chlist});
260 print_txpower($ch);
261
262 $indent--;
263 add_line("};\n");
264
265 $r++;
266 }
267}
268
269sub print_bands($) {
270 my $bands = shift;
271
272 foreach my $band_idx (sort keys %$bands) {
273 my $band = $bands->{$band_idx};
274
275 optimize_channels($band);
276
277 add_line("txpower-".$band->{type}."g {\n");
278 $indent++;
279
280 print_channels($band);
281
282 $indent--;
283 add_line("};\n");
284 };
285}
286
287my @files;
288my $cur = {};
289
290$chip_type = $chip_types{$chip} or die "Unsupported chip type '$chip', supported chip types: ".join(", ",sort keys %chip_types)."\n";
291
292while (@ARGV > 0) {
293 my $arg = shift @ARGV;
294
295 $cur or $cur = {
296 country => [],
297 regdomain => [],
298 };
299
300 if ($arg =~ /country=(\w+)$/) {
301 push @{$cur->{country}}, $1;
302 } elsif ($arg =~ /regdomain=(\w+)$/) {
303 push @{$cur->{regdomain}}, $1;
304 } else {
305 $cur->{bands} = read_data($arg);
306 push @files, $cur;
307 $cur = undef;
308 }
309}
310
311
312add_line("power-limits {\n");
313$indent++;
314
315my $count = 0;
316
317foreach my $domain (@files) {
318 my $name = "r$count";
319 $count++;
320
321 add_line("$name {\n");
322 $indent++;
323
324 add_named_string_array($domain, "country");
325 add_named_string_array($domain, "regdomain");
326 print_bands($domain->{bands});
327
328 $indent--;
329 add_line("};\n");
330}
331
332$indent--;
333add_line("};\n");