aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSylvain Munaut <tnt@246tNt.com>2020-05-05 21:06:33 +0200
committerSylvain Munaut <tnt@246tNt.com>2020-05-08 15:16:15 +0200
commit4a048d363b7e6c63816b9ae4d30cadabefed0a1a (patch)
treed8531b1f8db36882db7e2c6f9904021a42ae7031
parent586c0114b38e73ca5a862067f00410bb0e2a8cc8 (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
-rw-r--r--src/osmo-bsc/abis_om2000.c45
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;