diff options
author | Sylvain Munaut <tnt@246tNt.com> | 2020-05-05 21:06:33 +0200 |
---|---|---|
committer | Sylvain Munaut <tnt@246tNt.com> | 2020-05-08 15:16:15 +0200 |
commit | 4a048d363b7e6c63816b9ae4d30cadabefed0a1a (patch) | |
tree | d8531b1f8db36882db7e2c6f9904021a42ae7031 /src | |
parent | 586c0114b38e73ca5a862067f00410bb0e2a8cc8 (diff) |
om2k: Fix the frequency specifier for TX/RX/TS conf requests
* OM2K_DEI_FREQ_SPEC_RX:
(hop << 15) | (rx_addr << 10) | arfcn
. hop Hopping marker
. rx_addr is not really the TRX number, it's just a sequential number
different for all TRX, doesn't need to be 'in-order' of TRX
. arfcn The ARFCN number (0 for hopping and 1023 for 'no frequency')
* OM2K_DEI_FREQ_SPEC_TX:
(hop << 15) | (tx_id << 10) | arfcn
tx_id Pretty much same as rx_id except here we know that the order
doesn't have to match TRX order. It seems to even vary from one
reboot to another on some real-world capture we got.
. hop Hopping marker
. tx_addr Same as 'rx_addr' above but for TX
. arfcn The ARFCN number (0 for hopping and 1023 for 'no frequency')
* OM2K_DEI_FREQ_LIST:
Groups of 3 bytes (24 bits), 1 per frequency used.
(tx_addr << 20) | (rx_addr << 16) | (is_c0 << 10) | arfcn
. tx_addr See above
. rx_addr See above
. is_c0 Must be 1 if that ARFCN hosts the C0. (first TRX of a MCTR)
. arfcn The ARFCN number
(Note MAIO must also be set properly on the different TRX/TS sharing
a frequency ... )
The way we generate theses here is what we gathered from real-world
traces:
- Each 'TX' of each TRX is set to the ARFCN set in that TRX config
- Each 'RX' of each TRX is configures as 'hopping'
(which I assume means it will just pick the appropriate freq ?)
- For each TS, we use :
. tx_addr of the TRX that has the ARFCN we want to TX on
. rx_addr of the TRX where the TS we're configuring is
. arfcn The actual ARFCN we want to add to the list
This is incomplete but will work for the 1 MCTR case.
Config for multiple MCTR or multiple virtual-bts still need to be
handled but it's not yet known exactly how those need to be
configured.
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
Change-Id: Ie39a857543adaa11d1822346d8563ce3718412c8
Diffstat (limited to 'src')
-rw-r--r-- | src/osmo-bsc/abis_om2000.c | 45 |
1 files changed, 38 insertions, 7 deletions
diff --git a/src/osmo-bsc/abis_om2000.c b/src/osmo-bsc/abis_om2000.c index 9ae5a2644..e20d9a65e 100644 --- a/src/osmo-bsc/abis_om2000.c +++ b/src/osmo-bsc/abis_om2000.c @@ -1285,7 +1285,8 @@ int abis_om2k_tx_rx_conf_req(struct gsm_bts_trx *trx) o2k = (struct abis_om2k_hdr *) msgb_put(msg, sizeof(*o2k)); fill_om2k_hdr(o2k, &mo, OM2K_MSGT_RX_CONF_REQ); - msgb_tv16_put(msg, OM2K_DEI_FREQ_SPEC_RX, trx->arfcn); + /* OM2K_DEI_FREQ_SPEC_RX: Using trx_nr as "RX address" only works for single MCTR case */ + msgb_tv16_put(msg, OM2K_DEI_FREQ_SPEC_RX, 0x8000 | ((uint16_t)trx->nr << 10)); msgb_tv_put(msg, OM2K_DEI_RX_DIVERSITY, 0x02); /* A */ return abis_om2k_sendmsg(trx->bts, msg); @@ -1303,9 +1304,10 @@ int abis_om2k_tx_tx_conf_req(struct gsm_bts_trx *trx) o2k = (struct abis_om2k_hdr *) msgb_put(msg, sizeof(*o2k)); fill_om2k_hdr(o2k, &mo, OM2K_MSGT_TX_CONF_REQ); - msgb_tv16_put(msg, OM2K_DEI_FREQ_SPEC_TX, trx->arfcn); + /* OM2K_DEI_FREQ_SPEC_TX: Using trx_nr as "TX address" only works for single MCTR case */ + msgb_tv16_put(msg, OM2K_DEI_FREQ_SPEC_TX, trx->arfcn | ((uint16_t)trx->nr << 10)); msgb_tv_put(msg, OM2K_DEI_POWER, trx->nominal_power-trx->max_power_red); - msgb_tv_put(msg, OM2K_DEI_FILLING_MARKER, 0); /* Filling enabled */ + msgb_tv_put(msg, OM2K_DEI_FILLING_MARKER, trx != trx->bts->c0); /* Filling enabled for C0 only */ msgb_tv_put(msg, OM2K_DEI_BCC, trx->bts->bsic & 0x7); /* Dedication Information is optional */ @@ -1378,12 +1380,41 @@ static uint8_t ts2comb(struct gsm_bts_trx_ts *ts) return pchan2comb(ts->pchan_from_config); } -static int put_freq_list(uint8_t *buf, uint16_t arfcn) +static int put_freq_list(uint8_t *buf, struct gsm_bts_trx_ts *ts, uint16_t arfcn) { - buf[0] = 0x00; /* TX/RX address */ + struct gsm_bts_trx *trx; + + /* Find the TRX that's configured for that ARFCN */ + llist_for_each_entry(trx, &ts->trx->bts->trx_list, list) + if (trx->arfcn == arfcn) + break; + + if (!trx || (trx->arfcn != arfcn)) { + LOGP(DNM, LOGL_ERROR, "Trying to use ARFCN %d for hopping with no TRX configured for it", arfcn); + return 0; + } + + /* + * [7:4] - TX address + * This must be the same number that was used when configuring the TX + * MO object with that target arfcn + * + * [3:0] - RX address + * The logical TRX number we're configuring the hopping sequence for + * This must basically match the MO object instance number + * + * ATM since we only support 1 MCTR, we use trx->nr + */ + buf[0] = (trx->nr << 4) | ts->trx->nr; + + /* ARFCN Number */ buf[1] = (arfcn >> 8); buf[2] = (arfcn & 0xff); + /* C0 marker */ + if (trx == trx->bts->c0) + buf[1] |= 0x04; + return 3; } @@ -1397,10 +1428,10 @@ static int om2k_gen_freq_list(uint8_t *list, struct gsm_bts_trx_ts *ts) unsigned int i; for (i = 0; i < ts->hopping.arfcns.data_len*8; i++) { if (bitvec_get_bit_pos(&ts->hopping.arfcns, i)) - cur += put_freq_list(cur, i); + cur += put_freq_list(cur, ts, i); } } else - cur += put_freq_list(cur, ts->trx->arfcn); + cur += put_freq_list(cur, ts, ts->trx->arfcn); len = cur - list; |