Deleted Added
full compact
if_bwn_phy_n_ppr.c (300016) if_bwn_phy_n_ppr.c (300190)
1/*
2
3 Broadcom B43 wireless driver
4 IEEE 802.11n PHY data tables
5
6 Copyright (c) 2008 Michael Buesch <m@bues.ch>
7 Copyright (c) 2010 Rafa�� Mi��ecki <zajec5@gmail.com>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; see the file COPYING. If not, write to
21 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
22 Boston, MA 02110-1301, USA.
23
24*/
25
26#include <sys/cdefs.h>
1/*
2
3 Broadcom B43 wireless driver
4 IEEE 802.11n PHY data tables
5
6 Copyright (c) 2008 Michael Buesch <m@bues.ch>
7 Copyright (c) 2010 Rafa�� Mi��ecki <zajec5@gmail.com>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; see the file COPYING. If not, write to
21 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
22 Boston, MA 02110-1301, USA.
23
24*/
25
26#include <sys/cdefs.h>
27__FBSDID("$FreeBSD: head/sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_ppr.c 300016 2016-05-17 07:09:24Z adrian $");
27__FBSDID("$FreeBSD: head/sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_ppr.c 300190 2016-05-19 04:45:50Z adrian $");
28
29/*
30 * The Broadcom Wireless LAN controller driver.
31 */
28
29/*
30 * The Broadcom Wireless LAN controller driver.
31 */
32#include "opt_wlan.h"
33#include "opt_bwn.h"
32
33#include <sys/param.h>
34#include <sys/systm.h>
35#include <sys/kernel.h>
36#include <sys/malloc.h>
37#include <sys/module.h>
38#include <sys/endian.h>
39#include <sys/errno.h>
40#include <sys/firmware.h>
41#include <sys/lock.h>
42#include <sys/mutex.h>
43#include <machine/bus.h>
44#include <machine/resource.h>
45#include <sys/bus.h>
46#include <sys/rman.h>
47#include <sys/socket.h>
48#include <sys/sockio.h>
49
50#include <net/ethernet.h>
51#include <net/if.h>
52#include <net/if_var.h>
53#include <net/if_arp.h>
54#include <net/if_dl.h>
55#include <net/if_llc.h>
56#include <net/if_media.h>
57#include <net/if_types.h>
58
59#include <dev/pci/pcivar.h>
60#include <dev/pci/pcireg.h>
61#include <dev/siba/siba_ids.h>
62#include <dev/siba/sibareg.h>
63#include <dev/siba/sibavar.h>
64
65#include <net80211/ieee80211_var.h>
66#include <net80211/ieee80211_radiotap.h>
67#include <net80211/ieee80211_regdomain.h>
68#include <net80211/ieee80211_phy.h>
69#include <net80211/ieee80211_ratectl.h>
70
71#include <dev/bwn/if_bwnreg.h>
72#include <dev/bwn/if_bwnvar.h>
73#include <dev/bwn/if_bwn_debug.h>
74#include <dev/bwn/if_bwn_util.h>
75#include <dev/bwn/if_bwn_phy_common.h>
76
77#include <gnu/dev/bwn/phy_n/if_bwn_phy_n_regs.h>
78#include <gnu/dev/bwn/phy_n/if_bwn_phy_n_ppr.h>
79
80#define ppr_for_each_entry(ppr, i, entry) \
81 for (i = 0, entry = &(ppr)->__all_rates[i]; \
82 i < BWN_PPR_RATES_NUM; \
83 i++, entry++)
84
85void bwn_ppr_clear(struct bwn_mac *mac, struct bwn_ppr *ppr)
86{
87 memset(ppr, 0, sizeof(*ppr));
88
89 /* Compile-time PPR check */
90 CTASSERT(sizeof(struct bwn_ppr) == BWN_PPR_RATES_NUM * sizeof(uint8_t));
91}
92
93void bwn_ppr_add(struct bwn_mac *mac, struct bwn_ppr *ppr, int diff)
94{
95 int i;
96 uint8_t *rate;
97
98 ppr_for_each_entry(ppr, i, rate) {
99 *rate = bwn_clamp_val(*rate + diff, 0, 127);
100 }
101}
102
103void bwn_ppr_apply_max(struct bwn_mac *mac, struct bwn_ppr *ppr, uint8_t max)
104{
105 int i;
106 uint8_t *rate;
107
108 ppr_for_each_entry(ppr, i, rate) {
109 *rate = min(*rate, max);
110 }
111}
112
113void bwn_ppr_apply_min(struct bwn_mac *mac, struct bwn_ppr *ppr, uint8_t min)
114{
115 int i;
116 uint8_t *rate;
117
118 ppr_for_each_entry(ppr, i, rate) {
119 *rate = max(*rate, min);
120 }
121}
122
123uint8_t bwn_ppr_get_max(struct bwn_mac *mac, struct bwn_ppr *ppr)
124{
125 uint8_t res = 0;
126 int i;
127 uint8_t *rate;
128
129 ppr_for_each_entry(ppr, i, rate) {
130 res = max(*rate, res);
131 }
132
133 return res;
134}
135
136bool bwn_ppr_load_max_from_sprom(struct bwn_mac *mac, struct bwn_ppr *ppr,
137 bwn_phy_band_t band)
138{
139 struct bwn_softc *sc = mac->mac_sc;
140 struct siba_sprom_core_pwr_info core_pwr_info[4];
141 struct bwn_ppr_rates *rates = &ppr->rates;
142 struct bwn_phy *phy = &mac->mac_phy;
143 uint8_t maxpwr, off;
144 uint32_t sprom_ofdm_po;
145 uint16_t sprom_mcs_po[8];
146 uint8_t extra_cdd_po, extra_stbc_po;
147 int i;
148
149 for (i = 0; i < 4; i++) {
150 bzero(&core_pwr_info[i], sizeof(core_pwr_info[i]));
151 if (siba_sprom_get_core_power_info(sc->sc_dev, i,
152 &core_pwr_info[i]) != 0) {
153 BWN_ERRPRINTF(mac->mac_sc,
154 "%s: failed to get core_pwr_info for core %d\n",
155 __func__,
156 i);
157 }
158 }
159
160 switch (band) {
161 case BWN_PHY_BAND_2G:
162 maxpwr = min(core_pwr_info[0].maxpwr_2g,
163 core_pwr_info[1].maxpwr_2g);
164 sprom_ofdm_po = siba_sprom_get_ofdm2gpo(sc->sc_dev);
165 siba_sprom_get_mcs2gpo(sc->sc_dev, sprom_mcs_po);
166 extra_cdd_po = (siba_sprom_get_cddpo(sc->sc_dev) >> 0) & 0xf;
167 extra_stbc_po = (siba_sprom_get_stbcpo(sc->sc_dev) >> 0) & 0xf;
168 break;
169 case BWN_PHY_BAND_5G_LO:
170 maxpwr = min(core_pwr_info[0].maxpwr_5gl,
171 core_pwr_info[1].maxpwr_5gl);
172 sprom_ofdm_po = siba_sprom_get_ofdm5glpo(sc->sc_dev);
173 siba_sprom_get_mcs5glpo(sc->sc_dev, sprom_mcs_po);
174 extra_cdd_po = (siba_sprom_get_cddpo(sc->sc_dev) >> 8) & 0xf;
175 extra_stbc_po = (siba_sprom_get_stbcpo(sc->sc_dev) >> 8) & 0xf;
176 break;
177 case BWN_PHY_BAND_5G_MI:
178 maxpwr = min(core_pwr_info[0].maxpwr_5g,
179 core_pwr_info[1].maxpwr_5g);
180 sprom_ofdm_po = siba_sprom_get_ofdm5gpo(sc->sc_dev);
181 siba_sprom_get_mcs5gpo(sc->sc_dev, sprom_mcs_po);
182 extra_cdd_po = (siba_sprom_get_cddpo(sc->sc_dev) >> 4) & 0xf;
183 extra_stbc_po = (siba_sprom_get_stbcpo(sc->sc_dev) >> 4) & 0xf;
184 break;
185 case BWN_PHY_BAND_5G_HI:
186 maxpwr = min(core_pwr_info[0].maxpwr_5gh,
187 core_pwr_info[1].maxpwr_5gh);
188 sprom_ofdm_po = siba_sprom_get_ofdm5ghpo(sc->sc_dev);
189 siba_sprom_get_mcs5ghpo(sc->sc_dev, sprom_mcs_po);
190 extra_cdd_po = (siba_sprom_get_cddpo(sc->sc_dev) >> 12) & 0xf;
191 extra_stbc_po = (siba_sprom_get_stbcpo(sc->sc_dev) >> 12) & 0xf;
192 break;
193 default:
194 device_printf(mac->mac_sc->sc_dev, "%s: invalid band (%d)\n",
195 __func__,
196 band);
197 return false;
198 }
199
200 if (band == BWN_BAND_2G) {
201 for (i = 0; i < 4; i++) {
202 off = ((siba_sprom_get_cck2gpo(sc->sc_dev) >> (i * 4)) & 0xf) * 2;
203 rates->cck[i] = maxpwr - off;
204 }
205 }
206
207 /* OFDM */
208 for (i = 0; i < 8; i++) {
209 off = ((sprom_ofdm_po >> (i * 4)) & 0xf) * 2;
210 rates->ofdm[i] = maxpwr - off;
211 }
212
213 /* MCS 20 SISO */
214 rates->mcs_20[0] = rates->ofdm[0];
215 rates->mcs_20[1] = rates->ofdm[2];
216 rates->mcs_20[2] = rates->ofdm[3];
217 rates->mcs_20[3] = rates->ofdm[4];
218 rates->mcs_20[4] = rates->ofdm[5];
219 rates->mcs_20[5] = rates->ofdm[6];
220 rates->mcs_20[6] = rates->ofdm[7];
221 rates->mcs_20[7] = rates->ofdm[7];
222
223 /* MCS 20 CDD */
224 for (i = 0; i < 4; i++) {
225 off = ((sprom_mcs_po[0] >> (i * 4)) & 0xf) * 2;
226 rates->mcs_20_cdd[i] = maxpwr - off;
227 if (phy->type == BWN_PHYTYPE_N && phy->rev >= 3)
228 rates->mcs_20_cdd[i] -= extra_cdd_po;
229 }
230 for (i = 0; i < 4; i++) {
231 off = ((sprom_mcs_po[1] >> (i * 4)) & 0xf) * 2;
232 rates->mcs_20_cdd[4 + i] = maxpwr - off;
233 if (phy->type == BWN_PHYTYPE_N && phy->rev >= 3)
234 rates->mcs_20_cdd[4 + i] -= extra_cdd_po;
235 }
236
237 /* OFDM 20 CDD */
238 rates->ofdm_20_cdd[0] = rates->mcs_20_cdd[0];
239 rates->ofdm_20_cdd[1] = rates->mcs_20_cdd[0];
240 rates->ofdm_20_cdd[2] = rates->mcs_20_cdd[1];
241 rates->ofdm_20_cdd[3] = rates->mcs_20_cdd[2];
242 rates->ofdm_20_cdd[4] = rates->mcs_20_cdd[3];
243 rates->ofdm_20_cdd[5] = rates->mcs_20_cdd[4];
244 rates->ofdm_20_cdd[6] = rates->mcs_20_cdd[5];
245 rates->ofdm_20_cdd[7] = rates->mcs_20_cdd[6];
246
247 /* MCS 20 STBC */
248 for (i = 0; i < 4; i++) {
249 off = ((sprom_mcs_po[0] >> (i * 4)) & 0xf) * 2;
250 rates->mcs_20_stbc[i] = maxpwr - off;
251 if (phy->type == BWN_PHYTYPE_N && phy->rev >= 3)
252 rates->mcs_20_stbc[i] -= extra_stbc_po;
253 }
254 for (i = 0; i < 4; i++) {
255 off = ((sprom_mcs_po[1] >> (i * 4)) & 0xf) * 2;
256 rates->mcs_20_stbc[4 + i] = maxpwr - off;
257 if (phy->type == BWN_PHYTYPE_N && phy->rev >= 3)
258 rates->mcs_20_stbc[4 + i] -= extra_stbc_po;
259 }
260
261 /* MCS 20 SDM */
262 for (i = 0; i < 4; i++) {
263 off = ((sprom_mcs_po[2] >> (i * 4)) & 0xf) * 2;
264 rates->mcs_20_sdm[i] = maxpwr - off;
265 }
266 for (i = 0; i < 4; i++) {
267 off = ((sprom_mcs_po[3] >> (i * 4)) & 0xf) * 2;
268 rates->mcs_20_sdm[4 + i] = maxpwr - off;
269 }
270
271 return true;
272}
34
35#include <sys/param.h>
36#include <sys/systm.h>
37#include <sys/kernel.h>
38#include <sys/malloc.h>
39#include <sys/module.h>
40#include <sys/endian.h>
41#include <sys/errno.h>
42#include <sys/firmware.h>
43#include <sys/lock.h>
44#include <sys/mutex.h>
45#include <machine/bus.h>
46#include <machine/resource.h>
47#include <sys/bus.h>
48#include <sys/rman.h>
49#include <sys/socket.h>
50#include <sys/sockio.h>
51
52#include <net/ethernet.h>
53#include <net/if.h>
54#include <net/if_var.h>
55#include <net/if_arp.h>
56#include <net/if_dl.h>
57#include <net/if_llc.h>
58#include <net/if_media.h>
59#include <net/if_types.h>
60
61#include <dev/pci/pcivar.h>
62#include <dev/pci/pcireg.h>
63#include <dev/siba/siba_ids.h>
64#include <dev/siba/sibareg.h>
65#include <dev/siba/sibavar.h>
66
67#include <net80211/ieee80211_var.h>
68#include <net80211/ieee80211_radiotap.h>
69#include <net80211/ieee80211_regdomain.h>
70#include <net80211/ieee80211_phy.h>
71#include <net80211/ieee80211_ratectl.h>
72
73#include <dev/bwn/if_bwnreg.h>
74#include <dev/bwn/if_bwnvar.h>
75#include <dev/bwn/if_bwn_debug.h>
76#include <dev/bwn/if_bwn_util.h>
77#include <dev/bwn/if_bwn_phy_common.h>
78
79#include <gnu/dev/bwn/phy_n/if_bwn_phy_n_regs.h>
80#include <gnu/dev/bwn/phy_n/if_bwn_phy_n_ppr.h>
81
82#define ppr_for_each_entry(ppr, i, entry) \
83 for (i = 0, entry = &(ppr)->__all_rates[i]; \
84 i < BWN_PPR_RATES_NUM; \
85 i++, entry++)
86
87void bwn_ppr_clear(struct bwn_mac *mac, struct bwn_ppr *ppr)
88{
89 memset(ppr, 0, sizeof(*ppr));
90
91 /* Compile-time PPR check */
92 CTASSERT(sizeof(struct bwn_ppr) == BWN_PPR_RATES_NUM * sizeof(uint8_t));
93}
94
95void bwn_ppr_add(struct bwn_mac *mac, struct bwn_ppr *ppr, int diff)
96{
97 int i;
98 uint8_t *rate;
99
100 ppr_for_each_entry(ppr, i, rate) {
101 *rate = bwn_clamp_val(*rate + diff, 0, 127);
102 }
103}
104
105void bwn_ppr_apply_max(struct bwn_mac *mac, struct bwn_ppr *ppr, uint8_t max)
106{
107 int i;
108 uint8_t *rate;
109
110 ppr_for_each_entry(ppr, i, rate) {
111 *rate = min(*rate, max);
112 }
113}
114
115void bwn_ppr_apply_min(struct bwn_mac *mac, struct bwn_ppr *ppr, uint8_t min)
116{
117 int i;
118 uint8_t *rate;
119
120 ppr_for_each_entry(ppr, i, rate) {
121 *rate = max(*rate, min);
122 }
123}
124
125uint8_t bwn_ppr_get_max(struct bwn_mac *mac, struct bwn_ppr *ppr)
126{
127 uint8_t res = 0;
128 int i;
129 uint8_t *rate;
130
131 ppr_for_each_entry(ppr, i, rate) {
132 res = max(*rate, res);
133 }
134
135 return res;
136}
137
138bool bwn_ppr_load_max_from_sprom(struct bwn_mac *mac, struct bwn_ppr *ppr,
139 bwn_phy_band_t band)
140{
141 struct bwn_softc *sc = mac->mac_sc;
142 struct siba_sprom_core_pwr_info core_pwr_info[4];
143 struct bwn_ppr_rates *rates = &ppr->rates;
144 struct bwn_phy *phy = &mac->mac_phy;
145 uint8_t maxpwr, off;
146 uint32_t sprom_ofdm_po;
147 uint16_t sprom_mcs_po[8];
148 uint8_t extra_cdd_po, extra_stbc_po;
149 int i;
150
151 for (i = 0; i < 4; i++) {
152 bzero(&core_pwr_info[i], sizeof(core_pwr_info[i]));
153 if (siba_sprom_get_core_power_info(sc->sc_dev, i,
154 &core_pwr_info[i]) != 0) {
155 BWN_ERRPRINTF(mac->mac_sc,
156 "%s: failed to get core_pwr_info for core %d\n",
157 __func__,
158 i);
159 }
160 }
161
162 switch (band) {
163 case BWN_PHY_BAND_2G:
164 maxpwr = min(core_pwr_info[0].maxpwr_2g,
165 core_pwr_info[1].maxpwr_2g);
166 sprom_ofdm_po = siba_sprom_get_ofdm2gpo(sc->sc_dev);
167 siba_sprom_get_mcs2gpo(sc->sc_dev, sprom_mcs_po);
168 extra_cdd_po = (siba_sprom_get_cddpo(sc->sc_dev) >> 0) & 0xf;
169 extra_stbc_po = (siba_sprom_get_stbcpo(sc->sc_dev) >> 0) & 0xf;
170 break;
171 case BWN_PHY_BAND_5G_LO:
172 maxpwr = min(core_pwr_info[0].maxpwr_5gl,
173 core_pwr_info[1].maxpwr_5gl);
174 sprom_ofdm_po = siba_sprom_get_ofdm5glpo(sc->sc_dev);
175 siba_sprom_get_mcs5glpo(sc->sc_dev, sprom_mcs_po);
176 extra_cdd_po = (siba_sprom_get_cddpo(sc->sc_dev) >> 8) & 0xf;
177 extra_stbc_po = (siba_sprom_get_stbcpo(sc->sc_dev) >> 8) & 0xf;
178 break;
179 case BWN_PHY_BAND_5G_MI:
180 maxpwr = min(core_pwr_info[0].maxpwr_5g,
181 core_pwr_info[1].maxpwr_5g);
182 sprom_ofdm_po = siba_sprom_get_ofdm5gpo(sc->sc_dev);
183 siba_sprom_get_mcs5gpo(sc->sc_dev, sprom_mcs_po);
184 extra_cdd_po = (siba_sprom_get_cddpo(sc->sc_dev) >> 4) & 0xf;
185 extra_stbc_po = (siba_sprom_get_stbcpo(sc->sc_dev) >> 4) & 0xf;
186 break;
187 case BWN_PHY_BAND_5G_HI:
188 maxpwr = min(core_pwr_info[0].maxpwr_5gh,
189 core_pwr_info[1].maxpwr_5gh);
190 sprom_ofdm_po = siba_sprom_get_ofdm5ghpo(sc->sc_dev);
191 siba_sprom_get_mcs5ghpo(sc->sc_dev, sprom_mcs_po);
192 extra_cdd_po = (siba_sprom_get_cddpo(sc->sc_dev) >> 12) & 0xf;
193 extra_stbc_po = (siba_sprom_get_stbcpo(sc->sc_dev) >> 12) & 0xf;
194 break;
195 default:
196 device_printf(mac->mac_sc->sc_dev, "%s: invalid band (%d)\n",
197 __func__,
198 band);
199 return false;
200 }
201
202 if (band == BWN_BAND_2G) {
203 for (i = 0; i < 4; i++) {
204 off = ((siba_sprom_get_cck2gpo(sc->sc_dev) >> (i * 4)) & 0xf) * 2;
205 rates->cck[i] = maxpwr - off;
206 }
207 }
208
209 /* OFDM */
210 for (i = 0; i < 8; i++) {
211 off = ((sprom_ofdm_po >> (i * 4)) & 0xf) * 2;
212 rates->ofdm[i] = maxpwr - off;
213 }
214
215 /* MCS 20 SISO */
216 rates->mcs_20[0] = rates->ofdm[0];
217 rates->mcs_20[1] = rates->ofdm[2];
218 rates->mcs_20[2] = rates->ofdm[3];
219 rates->mcs_20[3] = rates->ofdm[4];
220 rates->mcs_20[4] = rates->ofdm[5];
221 rates->mcs_20[5] = rates->ofdm[6];
222 rates->mcs_20[6] = rates->ofdm[7];
223 rates->mcs_20[7] = rates->ofdm[7];
224
225 /* MCS 20 CDD */
226 for (i = 0; i < 4; i++) {
227 off = ((sprom_mcs_po[0] >> (i * 4)) & 0xf) * 2;
228 rates->mcs_20_cdd[i] = maxpwr - off;
229 if (phy->type == BWN_PHYTYPE_N && phy->rev >= 3)
230 rates->mcs_20_cdd[i] -= extra_cdd_po;
231 }
232 for (i = 0; i < 4; i++) {
233 off = ((sprom_mcs_po[1] >> (i * 4)) & 0xf) * 2;
234 rates->mcs_20_cdd[4 + i] = maxpwr - off;
235 if (phy->type == BWN_PHYTYPE_N && phy->rev >= 3)
236 rates->mcs_20_cdd[4 + i] -= extra_cdd_po;
237 }
238
239 /* OFDM 20 CDD */
240 rates->ofdm_20_cdd[0] = rates->mcs_20_cdd[0];
241 rates->ofdm_20_cdd[1] = rates->mcs_20_cdd[0];
242 rates->ofdm_20_cdd[2] = rates->mcs_20_cdd[1];
243 rates->ofdm_20_cdd[3] = rates->mcs_20_cdd[2];
244 rates->ofdm_20_cdd[4] = rates->mcs_20_cdd[3];
245 rates->ofdm_20_cdd[5] = rates->mcs_20_cdd[4];
246 rates->ofdm_20_cdd[6] = rates->mcs_20_cdd[5];
247 rates->ofdm_20_cdd[7] = rates->mcs_20_cdd[6];
248
249 /* MCS 20 STBC */
250 for (i = 0; i < 4; i++) {
251 off = ((sprom_mcs_po[0] >> (i * 4)) & 0xf) * 2;
252 rates->mcs_20_stbc[i] = maxpwr - off;
253 if (phy->type == BWN_PHYTYPE_N && phy->rev >= 3)
254 rates->mcs_20_stbc[i] -= extra_stbc_po;
255 }
256 for (i = 0; i < 4; i++) {
257 off = ((sprom_mcs_po[1] >> (i * 4)) & 0xf) * 2;
258 rates->mcs_20_stbc[4 + i] = maxpwr - off;
259 if (phy->type == BWN_PHYTYPE_N && phy->rev >= 3)
260 rates->mcs_20_stbc[4 + i] -= extra_stbc_po;
261 }
262
263 /* MCS 20 SDM */
264 for (i = 0; i < 4; i++) {
265 off = ((sprom_mcs_po[2] >> (i * 4)) & 0xf) * 2;
266 rates->mcs_20_sdm[i] = maxpwr - off;
267 }
268 for (i = 0; i < 4; i++) {
269 off = ((sprom_mcs_po[3] >> (i * 4)) & 0xf) * 2;
270 rates->mcs_20_sdm[4 + i] = maxpwr - off;
271 }
272
273 return true;
274}