diff options
Diffstat (limited to 'src/osmo-bts-octphy')
-rw-r--r-- | src/osmo-bts-octphy/l1_if.c | 170 | ||||
-rw-r--r-- | src/osmo-bts-octphy/l1_if.h | 31 | ||||
-rw-r--r-- | src/osmo-bts-octphy/l1_oml.c | 163 | ||||
-rw-r--r-- | src/osmo-bts-octphy/main.c | 3 | ||||
-rw-r--r-- | src/osmo-bts-octphy/octphy_hw_api.c | 14 | ||||
-rw-r--r-- | src/osmo-bts-octphy/octphy_vty.c | 198 |
6 files changed, 348 insertions, 231 deletions
diff --git a/src/osmo-bts-octphy/l1_if.c b/src/osmo-bts-octphy/l1_if.c index db6e032c..3215aa19 100644 --- a/src/osmo-bts-octphy/l1_if.c +++ b/src/osmo-bts-octphy/l1_if.c @@ -38,6 +38,7 @@ #include <osmocom/core/socket.h> #include <osmo-bts/gsm_data.h> +#include <osmo-bts/bts_model.h> #include <osmo-bts/oml.h> #include <osmo-bts/logging.h> #include <osmo-bts/l1sap.h> @@ -109,6 +110,17 @@ osmocom_to_octphy_band(enum gsm_band osmo_band, unsigned int arfcn) } }; +struct gsm_bts_trx *trx_by_l1h(struct octphy_hdl *fl1h, unsigned int trx_id) +{ + struct phy_instance *pinst; + + pinst = phy_instance_by_num(fl1h->phy_link, trx_id); + if (!pinst) + return NULL; + + return pinst->trx; +} + struct gsm_lchan *get_lchan_by_lchid(struct gsm_bts_trx *trx, tOCTVC1_GSM_LOGICAL_CHANNEL_ID *lch_id) { @@ -282,10 +294,9 @@ int l1if_req_compl(struct octphy_hdl *fl1h, struct msgb *msg, } /* For OctPHY, this only about sending state changes to BSC */ -int l1if_activate_rf(struct octphy_hdl *fl1h, int on) +int l1if_activate_rf(struct gsm_bts_trx *trx, int on) { int i; - struct gsm_bts_trx *trx = fl1h->priv; if (on) { /* signal availability */ oml_mo_state_chg(&trx->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OK); @@ -422,7 +433,8 @@ static void empty_req_from_rts_ind(tOCTVC1_GSM_MSG_TRX_REQUEST_LOGICAL_CHANNEL_E static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg, struct osmo_phsap_prim *l1sap) { - struct octphy_hdl *fl1h = trx_octphy_hdl(trx); + struct phy_instance *pinst = trx_phy_instance(trx); + struct octphy_hdl *fl1h = pinst->phy_link->u.octphy.hdl; struct msgb *l1msg = l1p_msgb_alloc(); uint32_t u32Fn; uint8_t u8Tn, subCh, sapi = 0; @@ -489,7 +501,7 @@ static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg, l1if_fill_msg_hdr(&data_req->Header, l1msg, fl1h, cOCTVC1_MSG_TYPE_COMMAND, cOCTVC1_GSM_MSG_TRX_REQUEST_LOGICAL_CHANNEL_DATA_CID); - data_req->TrxId.byTrxId = trx->nr; + data_req->TrxId.byTrxId = pinst->u.octphy.trx_id; data_req->LchId.byTimeslotNb = u8Tn; data_req->LchId.bySAPI = sapi; data_req->LchId.bySubChannelNb = subCh; @@ -508,7 +520,7 @@ static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg, l1if_fill_msg_hdr(&empty_frame_req->Header, l1msg, fl1h, cOCTVC1_MSG_TYPE_COMMAND, cOCTVC1_GSM_MSG_TRX_REQUEST_LOGICAL_CHANNEL_EMPTY_FRAME_CID); - empty_frame_req->TrxId.byTrxId = trx->nr; + empty_frame_req->TrxId.byTrxId = pinst->u.octphy.trx_id; empty_frame_req->LchId.byTimeslotNb = u8Tn; empty_frame_req->LchId.bySAPI = sapi; empty_frame_req->LchId.bySubChannelNb = subCh; @@ -527,7 +539,8 @@ done: static int ph_tch_req(struct gsm_bts_trx *trx, struct msgb *msg, struct osmo_phsap_prim *l1sap) { - struct octphy_hdl *fl1h = trx_octphy_hdl(trx); + struct phy_instance *pinst = trx_phy_instance(trx); + struct octphy_hdl *fl1h = pinst->phy_link->u.octphy.hdl; struct gsm_lchan *lchan; uint32_t u32Fn; uint8_t u8Tn, subCh, sapi, ss; @@ -565,7 +578,7 @@ static int ph_tch_req(struct gsm_bts_trx *trx, struct msgb *msg, l1if_fill_msg_hdr(&data_req->Header, nmsg, fl1h, cOCTVC1_MSG_TYPE_COMMAND, cOCTVC1_GSM_MSG_TRX_REQUEST_LOGICAL_CHANNEL_DATA_CID); - data_req->TrxId.byTrxId = trx->nr; + data_req->TrxId.byTrxId = pinst->u.octphy.trx_id; data_req->LchId.byTimeslotNb = u8Tn; data_req->LchId.bySAPI = sapi; data_req->LchId.bySubChannelNb = subCh; @@ -590,7 +603,7 @@ static int ph_tch_req(struct gsm_bts_trx *trx, struct msgb *msg, l1if_fill_msg_hdr(&empty_frame_req->Header, nmsg, fl1h, cOCTVC1_MSG_TYPE_COMMAND, cOCTVC1_GSM_MSG_TRX_REQUEST_LOGICAL_CHANNEL_EMPTY_FRAME_CID); - empty_frame_req->TrxId.byTrxId = trx->nr; + empty_frame_req->TrxId.byTrxId = pinst->u.octphy.trx_id; empty_frame_req->LchId.byTimeslotNb = u8Tn; empty_frame_req->LchId.bySAPI = sapi; empty_frame_req->LchId.bySubChannelNb = subCh; @@ -686,32 +699,78 @@ int bts_model_l1sap_down(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap) return rc; } +static int trx_close_all_cb(struct octphy_hdl *fl1, struct msgb *resp, void *data) +{ + tOCTVC1_GSM_MSG_TRX_CLOSE_ALL_RSP *car = + (tOCTVC1_GSM_MSG_TRX_CLOSE_ALL_RSP *) resp->l2h; + + /* in a completion call-back, we take msgb ownership and must + * release it before returning */ + + mOCTVC1_GSM_MSG_TRX_CLOSE_ALL_RSP_SWAP(car); + + /* we now know that the PHY link is connected */ + phy_link_state_set(fl1->phy_link, PHY_LINK_CONNECTED); + + msgb_free(resp); + + return 0; +} + +static int phy_link_trx_close_all(struct phy_link *plink) +{ + struct octphy_hdl *fl1h = plink->u.octphy.hdl; + struct msgb *msg = l1p_msgb_alloc(); + tOCTVC1_GSM_MSG_TRX_CLOSE_ALL_CMD *cac; + + cac = (tOCTVC1_GSM_MSG_TRX_CLOSE_ALL_CMD *) + msgb_put(msg, sizeof(*cac)); + l1if_fill_msg_hdr(&cac->Header, msg, fl1h, cOCTVC1_MSG_TYPE_COMMAND, + cOCTVC1_GSM_MSG_TRX_CLOSE_ALL_CID); + + mOCTVC1_GSM_MSG_TRX_CLOSE_ALL_CMD_SWAP(cac); + + return l1if_req_compl(fl1h, msg, trx_close_all_cb, NULL); +} + +int bts_model_phy_link_open(struct phy_link *plink) +{ + if (plink->u.octphy.hdl) + l1if_close(plink->u.octphy.hdl); + + phy_link_state_set(plink, PHY_LINK_CONNECTING); + + plink->u.octphy.hdl = l1if_open(plink); + if (!plink->u.octphy.hdl) { + phy_link_state_set(plink, PHY_LINK_SHUTDOWN); + return -1; + } + + /* do we need to iterate over the list of instances and do some + * instance-specific initialization? */ + + /* close all TRXs that might still exist in this link from + * previous execitions / sessions */ + phy_link_trx_close_all(plink); + + /* in the call-back to the above we will set the link state to + * connected */ + + return 0; +} + int bts_model_init(struct gsm_bts *bts) { struct gsm_bts_role_bts *btsb; - struct octphy_hdl *fl1h; LOGP(DL1C, LOGL_NOTICE, "model_init()\n"); btsb = bts_role_bts(bts); btsb->support.ciphers = CIPHER_A5(1) | CIPHER_A5(2) | CIPHER_A5(3); - fl1h = talloc_zero(bts, struct octphy_hdl); - if (!fl1h) - return -ENOMEM; - - INIT_LLIST_HEAD(&fl1h->wlc_list); - INIT_LLIST_HEAD(&fl1h->wlc_postponed); - fl1h->priv = bts->c0; - bts->c0->role_bts.l1h = fl1h; /* FIXME: what is the nominal transmit power of the PHY/board? */ bts->c0->nominal_power = 15; - /* configure some reasonable defaults, to be overridden by VTY */ - fl1h->config.rf_port_index = 0; - fl1h->config.rx_gain_db = 70; - fl1h->config.tx_atten_db = 0; - bts_model_vty_init(bts); return 0; @@ -750,23 +809,15 @@ static void dump_meas_res(int ll, tOCTVC1_GSM_MEASUREMENT_INFO * m) static int handle_mph_time_ind(struct octphy_hdl *fl1, uint8_t trx_id, uint32_t fn) { - struct gsm_bts_trx *trx = fl1->priv; - struct gsm_bts *bts = trx->bts; + struct gsm_bts_trx *trx = trx_by_l1h(fl1, trx_id); struct osmo_phsap_prim l1sap; /* increment the primitive count for the alive timer */ fl1->alive_prim_cnt++; /* ignore every time indication, except for c0 */ - if (trx != bts->c0) - return 0; - - if (trx_id != trx->nr) { - LOGP(DL1C, LOGL_FATAL, - "TRX id %d from response does not match the L1 context trx %d\n", - trx_id, trx->nr); + if (trx != trx->bts->c0) return 0; - } memset(&l1sap, 0, sizeof(l1sap)); osmo_prim_init(&l1sap.oph, SAP_GSM_PH, PRIM_MPH_INFO, @@ -783,7 +834,7 @@ static int handle_ph_readytosend_ind(struct octphy_hdl *fl1, tOCTVC1_GSM_MSG_TRX_LOGICAL_CHANNEL_READY_TO_SEND_INDICATION_EVT *evt, struct msgb *l1p_msg) { - struct gsm_bts_trx *trx = fl1->priv; + struct gsm_bts_trx *trx = trx_by_l1h(fl1, evt->TrxId.byTrxId); struct gsm_bts *bts = trx->bts; struct osmo_phsap_prim *l1sap; struct gsm_time g_time; @@ -908,7 +959,7 @@ static int handle_ph_data_ind(struct octphy_hdl *fl1, tOCTVC1_GSM_MSG_TRX_LOGICAL_CHANNEL_DATA_INDICATION_EVT *data_ind, struct msgb *l1p_msg) { - struct gsm_bts_trx *trx = fl1->priv; + struct gsm_bts_trx *trx = trx_by_l1h(fl1, data_ind->TrxId.byTrxId); uint8_t chan_nr, link_id; struct osmo_phsap_prim *l1sap; uint32_t fn; @@ -992,7 +1043,7 @@ static int handle_ph_rach_ind(struct octphy_hdl *fl1, tOCTVC1_GSM_MSG_TRX_LOGICAL_CHANNEL_RACH_INDICATION_EVT *ra_ind, struct msgb *l1p_msg) { - struct gsm_bts_trx *trx = fl1->priv; + struct gsm_bts_trx *trx = trx_by_l1h(fl1, ra_ind->TrxId.byTrxId); struct gsm_bts *bts = trx->bts; struct gsm_bts_role_bts *btsb = bts_role_bts(bts); struct gsm_lchan *lchan; @@ -1131,7 +1182,7 @@ static int rx_octvc1_resp(struct msgb *msg, uint32_t msg_id, uint32_t trans_id) if (wlc->cb) { /* call-back function must take msgb * ownership. */ - rc = wlc->cb(fl1h->priv, msg, wlc->cb_data); + rc = wlc->cb(fl1h, msg, wlc->cb_data); } else { rc = 0; msgb_free(msg); @@ -1485,6 +1536,18 @@ static int rx_octphy_msg(struct msgb *msg) return rc; } +void bts_model_phy_link_set_defaults(struct phy_link *plink) +{ + /* configure some reasonable defaults, to be overridden by VTY */ + plink->u.octphy.rf_port_index = 0; + plink->u.octphy.rx_gain_db = 70; + plink->u.octphy.tx_atten_db = 0; +} + +void bts_model_phy_instance_set_defaults(struct phy_instance *pinst) +{ +} + /*********************************************************************** * octphy socket / main loop integration ***********************************************************************/ @@ -1534,15 +1597,25 @@ static int octphy_write_cb(struct osmo_fd *fd, struct msgb *msg) return rc; } -int l1if_open(struct octphy_hdl *fl1h) +struct octphy_hdl *l1if_open(struct phy_link *plink) { + struct octphy_hdl *fl1h; struct ifreq ifr; int sfd, rc; - char *phy_dev = fl1h->netdev_name; + char *phy_dev = plink->u.octphy.netdev_name; + + fl1h = talloc_zero(plink, struct octphy_hdl); + if (!fl1h) + return NULL; + + INIT_LLIST_HEAD(&fl1h->wlc_list); + INIT_LLIST_HEAD(&fl1h->wlc_postponed); + fl1h->phy_link = plink; if (!phy_dev) { LOGP(DL1C, LOGL_ERROR, "You have to specify a phy-netdev\n"); - return -EINVAL; + talloc_free(fl1h); + return NULL; } LOGP(DL1C, LOGL_NOTICE, "Opening L1 interface for OctPHY (%s)\n", @@ -1553,7 +1626,8 @@ int l1if_open(struct octphy_hdl *fl1h) if (sfd < 0) { LOGP(DL1C, LOGL_FATAL, "Error opening PHY socket: %s\n", strerror(errno)); - return -EIO; + talloc_free(fl1h); + return NULL; } /* resolve the string device name to an ifindex */ @@ -1564,18 +1638,21 @@ int l1if_open(struct octphy_hdl *fl1h) LOGP(DL1C, LOGL_FATAL, "Error using network device %s: %s\n", phy_dev, strerror(errno)); close(sfd); - return -EIO; + talloc_free(fl1h); + return NULL; } fl1h->session_id = rand(); - /* set fl1h->phy_addr, which we use as sendto() destionation */ + /* set fl1h->phy_addr, which we use as sendto() destination */ fl1h->phy_addr.sll_family = AF_PACKET; fl1h->phy_addr.sll_protocol = htons(cOCTPKT_HDR_ETHERTYPE); fl1h->phy_addr.sll_ifindex = ifr.ifr_ifindex; fl1h->phy_addr.sll_hatype = ARPHRD_ETHER; - fl1h->phy_addr.sll_halen = 6; - /* sll_addr is filled by bts_model_vty code */ + fl1h->phy_addr.sll_halen = ETH_ALEN; + /* plink->phy_addr.sll_addr is filled by bts_model_vty code */ + memcpy(fl1h->phy_addr.sll_addr, plink->u.octphy.phy_addr.sll_addr, + ETH_ALEN); /* Write queue / osmo_fd registration */ osmo_wqueue_init(&fl1h->phy_wq, 10); @@ -1588,10 +1665,11 @@ int l1if_open(struct octphy_hdl *fl1h) rc = osmo_fd_register(&fl1h->phy_wq.bfd); if (rc < 0) { close(sfd); - return -EIO; + talloc_free(fl1h); + return NULL; } - return 0; + return fl1h; } int l1if_close(struct octphy_hdl *fl1h) diff --git a/src/osmo-bts-octphy/l1_if.h b/src/osmo-bts-octphy/l1_if.h index 42778659..2dee178d 100644 --- a/src/osmo-bts-octphy/l1_if.h +++ b/src/osmo-bts-octphy/l1_if.h @@ -13,16 +13,16 @@ #include <osmocom/gsm/protocol/gsm_04_08.h> #include <osmo-bts/gsm_data.h> +#include <osmo-bts/phy_link.h> #include <octphy/octvc1/gsm/octvc1_gsm_api.h> struct octphy_hdl { + /* MAC address of the PHY */ + struct sockaddr_ll phy_addr; + /* packet socket to talk with PHY */ struct osmo_wqueue phy_wq; - /* MAC address of th PHY */ - struct sockaddr_ll phy_addr; - /* Network device name */ - char *netdev_name; /* address parameters of the PHY */ uint32_t session_id; @@ -33,12 +33,6 @@ struct octphy_hdl { uint32_t clkmgr_state; struct { - uint32_t rf_port_index; - uint32_t rx_gain_db; - uint32_t tx_atten_db; - } config; - - struct { struct { char *name; char *description; @@ -72,8 +66,8 @@ struct octphy_hdl { struct llist_head wlc_postponed; int wlc_postponed_len; - /* private pointer, points back to TRX */ - void *priv; + /* back pointer to the PHY link */ + struct phy_link *phy_link; struct osmo_timer_list alive_timer; uint32_t alive_prim_cnt; @@ -82,15 +76,10 @@ struct octphy_hdl { int opened; }; -static inline struct octphy_hdl *trx_octphy_hdl(struct gsm_bts_trx *trx) -{ - return trx->role_bts.l1h; -} - void l1if_fill_msg_hdr(tOCTVC1_MSG_HEADER *mh, struct msgb *msg, struct octphy_hdl *fl1h, uint32_t msg_type, uint32_t api_cmd); -typedef int l1if_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg, void *data); +typedef int l1if_compl_cb(struct octphy_hdl *fl1, struct msgb *l1_msg, void *data); /* send a request primitive to the L1 and schedule completion call-back */ int l1if_req_compl(struct octphy_hdl *fl1h, struct msgb *msg, @@ -100,19 +89,21 @@ int l1if_req_compl(struct octphy_hdl *fl1h, struct msgb *msg, struct gsm_lchan *get_lchan_by_lchid(struct gsm_bts_trx *trx, tOCTVC1_GSM_LOGICAL_CHANNEL_ID *lch_id); -int l1if_open(struct octphy_hdl *fl1h); +struct octphy_hdl *l1if_open(struct phy_link *plink); int l1if_close(struct octphy_hdl *hdl); int l1if_trx_open(struct gsm_bts_trx *trx); int l1if_trx_close_all(struct gsm_bts *bts); int l1if_enable_events(struct gsm_bts_trx *trx); -int l1if_activate_rf(struct octphy_hdl *fl1h, int on); +int l1if_activate_rf(struct gsm_bts_trx *trx, int on); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, tOCTVC1_GSM_MSG_TRX_LOGICAL_CHANNEL_DATA_INDICATION_EVT * data_ind); +struct gsm_bts_trx *trx_by_l1h(struct octphy_hdl *fl1h, unsigned int trx_id); + struct msgb *l1p_msgb_alloc(void); /* tch.c */ diff --git a/src/osmo-bts-octphy/l1_oml.c b/src/osmo-bts-octphy/l1_oml.c index 318c384e..c50f1d6a 100644 --- a/src/osmo-bts-octphy/l1_oml.c +++ b/src/osmo-bts-octphy/l1_oml.c @@ -348,10 +348,11 @@ static void sapi_clear_queue(struct llist_head *queue) } } -static int lchan_act_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, void *data) +static int lchan_act_compl_cb(struct octphy_hdl *fl1, struct msgb *resp, void *data) { tOCTVC1_GSM_MSG_TRX_ACTIVATE_LOGICAL_CHANNEL_RSP *ar = (tOCTVC1_GSM_MSG_TRX_ACTIVATE_LOGICAL_CHANNEL_RSP *) resp->l2h; + struct gsm_bts_trx *trx; struct gsm_lchan *lchan; uint8_t sapi; uint8_t direction; @@ -361,7 +362,7 @@ static int lchan_act_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, void * * release it before returning */ mOCTVC1_GSM_MSG_TRX_ACTIVATE_LOGICAL_CHANNEL_RSP_SWAP(ar); - OSMO_ASSERT(ar->TrxId.byTrxId == trx->nr); + trx = trx_by_l1h(fl1, ar->TrxId.byTrxId); lchan = get_lchan_by_lchid(trx, &ar->LchId); sapi = ar->LchId.bySAPI; @@ -411,7 +412,8 @@ err: static int mph_send_activate_req(struct gsm_lchan *lchan, struct sapi_cmd *cmd) { - struct octphy_hdl *fl1h = trx_octphy_hdl(lchan->ts->trx); + struct phy_instance *pinst = trx_phy_instance(lchan->ts->trx); + struct octphy_hdl *fl1h = pinst->phy_link->u.octphy.hdl; struct msgb *msg = l1p_msgb_alloc(); tOCTVC1_GSM_MSG_TRX_ACTIVATE_LOGICAL_CHANNEL_CMD *lac; @@ -420,7 +422,7 @@ static int mph_send_activate_req(struct gsm_lchan *lchan, struct sapi_cmd *cmd) l1if_fill_msg_hdr(&lac->Header, msg, fl1h, cOCTVC1_MSG_TYPE_COMMAND, cOCTVC1_GSM_MSG_TRX_ACTIVATE_LOGICAL_CHANNEL_CID); - lac->TrxId.byTrxId = lchan->ts->trx->nr; + lac->TrxId.byTrxId = pinst->u.octphy.trx_id; lac->LchId.byTimeslotNb = lchan->ts->nr; lac->LchId.bySubChannelNb = lchan_to_GsmL1_SubCh_t(lchan); lac->LchId.bySAPI = cmd->sapi; @@ -451,10 +453,11 @@ static tOCTVC1_GSM_CIPHERING_ID_ENUM rsl2l1_ciph[] = { [4] = cOCTVC1_GSM_CIPHERING_ID_ENUM_A5_3 }; -static int set_ciph_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, void *data) +static int set_ciph_compl_cb(struct octphy_hdl *fl1, struct msgb *resp, void *data) { tOCTVC1_GSM_MSG_TRX_MODIFY_PHYSICAL_CHANNEL_CIPHERING_RSP *pcr = (tOCTVC1_GSM_MSG_TRX_MODIFY_PHYSICAL_CHANNEL_CIPHERING_RSP *) resp->l2h; + struct gsm_bts_trx *trx; struct gsm_bts_trx_ts *ts; struct gsm_lchan *lchan; @@ -470,6 +473,7 @@ static int set_ciph_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, void *d exit(-1); } + trx = trx_by_l1h(fl1, pcr->TrxId.byTrxId); OSMO_ASSERT(pcr->TrxId.byTrxId == trx->nr); ts = &trx->ts[pcr->PchId.byTimeslotNb]; /* for some strange reason the response does not tell which @@ -508,8 +512,8 @@ err: static int mph_send_config_ciphering(struct gsm_lchan *lchan, struct sapi_cmd *cmd) { - struct gsm_bts_trx *trx = lchan->ts->trx; - struct octphy_hdl *fl1h = trx_octphy_hdl(trx); + struct phy_instance *pinst = trx_phy_instance(lchan->ts->trx); + struct octphy_hdl *fl1h = pinst->phy_link->u.octphy.hdl; struct msgb *msg = l1p_msgb_alloc(); tOCTVC1_GSM_MSG_TRX_MODIFY_PHYSICAL_CHANNEL_CIPHERING_CMD *pcc; @@ -518,6 +522,7 @@ static int mph_send_config_ciphering(struct gsm_lchan *lchan, struct sapi_cmd *c l1if_fill_msg_hdr(&pcc->Header, msg, fl1h, cOCTVC1_MSG_TYPE_COMMAND, cOCTVC1_GSM_MSG_TRX_MODIFY_PHYSICAL_CHANNEL_CIPHERING_CID); + pcc->TrxId.byTrxId = pinst->u.octphy.trx_id; pcc->PchId.byTimeslotNb = lchan->ts->nr; pcc->ulSubchannelNb = lchan_to_GsmL1_SubCh_t(lchan); pcc->ulDirection = cmd->dir; @@ -627,7 +632,8 @@ static int check_sapi_release(struct gsm_lchan *lchan, int sapi, int dir) static int lchan_deactivate_sapis(struct gsm_lchan *lchan) { - struct octphy_hdl *fl1h = trx_octphy_hdl(lchan->ts->trx); + struct phy_instance *pinst = trx_phy_instance(lchan->ts->trx); + struct octphy_hdl *fl1h = pinst->phy_link->u.octphy.hdl; const struct lchan_sapis *s4l = &sapis_for_lchan[lchan->type]; int i, res; @@ -654,10 +660,11 @@ static int lchan_deactivate_sapis(struct gsm_lchan *lchan) return res; } -static int lchan_deact_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, void *data) +static int lchan_deact_compl_cb(struct octphy_hdl *fl1, struct msgb *resp, void *data) { tOCTVC1_GSM_MSG_TRX_DEACTIVATE_LOGICAL_CHANNEL_RSP *ldr = (tOCTVC1_GSM_MSG_TRX_DEACTIVATE_LOGICAL_CHANNEL_RSP *) resp->l2h; + struct gsm_bts_trx *trx; struct gsm_lchan *lchan; struct sapi_cmd *cmd; uint8_t status; @@ -666,7 +673,7 @@ static int lchan_deact_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, void * release it before returning */ mOCTVC1_GSM_MSG_TRX_DEACTIVATE_LOGICAL_CHANNEL_RSP_SWAP(ldr); - OSMO_ASSERT(ldr->TrxId.byTrxId == trx->nr); + trx = trx_by_l1h(fl1, ldr->TrxId.byTrxId); lchan = get_lchan_by_lchid(trx, &ldr->LchId); @@ -725,7 +732,8 @@ err: static int mph_send_deactivate_req(struct gsm_lchan *lchan, struct sapi_cmd *cmd) { - struct octphy_hdl *fl1h = trx_octphy_hdl(lchan->ts->trx); + struct phy_instance *pinst = trx_phy_instance(lchan->ts->trx); + struct octphy_hdl *fl1h = pinst->phy_link->u.octphy.hdl; struct msgb *msg = l1p_msgb_alloc(); tOCTVC1_GSM_MSG_TRX_DEACTIVATE_LOGICAL_CHANNEL_CMD *ldc; @@ -734,6 +742,7 @@ static int mph_send_deactivate_req(struct gsm_lchan *lchan, struct sapi_cmd *cmd l1if_fill_msg_hdr(&ldc->Header, msg, fl1h,cOCTVC1_MSG_TYPE_COMMAND, cOCTVC1_GSM_MSG_TRX_DEACTIVATE_LOGICAL_CHANNEL_CID); + ldc->TrxId.byTrxId = pinst->u.octphy.trx_id; ldc->LchId.byTimeslotNb = lchan->ts->nr; ldc->LchId.bySubChannelNb = lchan_to_GsmL1_SubCh_t(lchan); ldc->LchId.byDirection = cmd->dir; @@ -1031,7 +1040,8 @@ static void enqueue_sapi_act_cmd(struct gsm_lchan *lchan, int sapi, int dir) int lchan_activate(struct gsm_lchan *lchan) { - struct octphy_hdl *fl1h = trx_octphy_hdl(lchan->ts->trx); + struct phy_instance *pinst = trx_phy_instance(lchan->ts->trx); + struct octphy_hdl *fl1h = pinst->phy_link->u.octphy.hdl; const struct lchan_sapis *s4l = &sapis_for_lchan[lchan->type]; unsigned int i; @@ -1069,7 +1079,7 @@ int l1if_rsl_chan_act(struct gsm_lchan *lchan) return 0; } -static int enable_events_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, void *data) +static int enable_events_compl_cb(struct octphy_hdl *fl1, struct msgb *resp, void *data) { tOCTVC1_MAIN_MSG_API_SYSTEM_MODIFY_SESSION_EVT_RSP *mser = (tOCTVC1_MAIN_MSG_API_SYSTEM_MODIFY_SESSION_EVT_RSP *) resp->l2h; @@ -1088,7 +1098,8 @@ static int enable_events_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, vo int l1if_enable_events(struct gsm_bts_trx *trx) { - struct octphy_hdl *fl1h = trx_octphy_hdl(trx); + struct phy_instance *pinst = trx_phy_instance(trx); + struct octphy_hdl *fl1h = pinst->phy_link->u.octphy.hdl; struct msgb *msg = l1p_msgb_alloc(); tOCTVC1_MAIN_MSG_API_SYSTEM_MODIFY_SESSION_EVT_CMD *mse; @@ -1112,9 +1123,8 @@ int l1if_enable_events(struct gsm_bts_trx *trx) dst = talloc_strdup(ctx, (const char *) src); \ } while (0) -static int app_info_sys_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, void *data) +static int app_info_sys_compl_cb(struct octphy_hdl *fl1h, struct msgb *resp, void *data) { - struct octphy_hdl *fl1h = resp->dst; tOCTVC1_MAIN_MSG_APPLICATION_INFO_SYSTEM_RSP *aisr = (tOCTVC1_MAIN_MSG_APPLICATION_INFO_SYSTEM_RSP *) resp->l2h; @@ -1136,7 +1146,8 @@ static int app_info_sys_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, voi int l1if_check_app_sys_version(struct gsm_bts_trx *trx) { - struct octphy_hdl *fl1h = trx_octphy_hdl(trx); + struct phy_instance *pinst = trx_phy_instance(trx); + struct octphy_hdl *fl1h = pinst->phy_link->u.octphy.hdl; struct msgb *msg = l1p_msgb_alloc(); tOCTVC1_MAIN_MSG_APPLICATION_INFO_SYSTEM_CMD *ais; @@ -1152,9 +1163,8 @@ int l1if_check_app_sys_version(struct gsm_bts_trx *trx) return l1if_req_compl(fl1h, msg, app_info_sys_compl_cb, 0); } -static int app_info_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, void *data) +static int app_info_compl_cb(struct octphy_hdl *fl1h, struct msgb *resp, void *data) { - struct octphy_hdl *fl1h = resp->dst; tOCTVC1_MAIN_MSG_APPLICATION_INFO_RSP *air = (tOCTVC1_MAIN_MSG_APPLICATION_INFO_RSP *) resp->l2h; @@ -1178,7 +1188,8 @@ static int app_info_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, void *d int l1if_check_app_version(struct gsm_bts_trx *trx) { - struct octphy_hdl *fl1h = trx_octphy_hdl(trx); + struct phy_instance *pinst = trx_phy_instance(trx); + struct octphy_hdl *fl1h = pinst->phy_link->u.octphy.hdl; struct msgb *msg = l1p_msgb_alloc(); tOCTVC1_MAIN_MSG_APPLICATION_INFO_CMD *ai; @@ -1193,9 +1204,50 @@ int l1if_check_app_version(struct gsm_bts_trx *trx) return l1if_req_compl(fl1h, msg, app_info_compl_cb, 0); } +static int trx_close_cb(struct octphy_hdl *fl1, struct msgb *resp, void *data) +{ + tOCTVC1_GSM_MSG_TRX_CLOSE_RSP *car = + (tOCTVC1_GSM_MSG_TRX_CLOSE_RSP *) resp->l2h; + + /* in a completion call-back, we take msgb ownership and must + * release it before returning */ + + mOCTVC1_GSM_MSG_TRX_CLOSE_RSP_SWAP(car); + + LOGP(DL1C, LOGL_INFO, "Rx TRX-CLOSE.conf(%u)\n", car->TrxId.byTrxId); + + msgb_free(resp); + + return 0; +} + +static int trx_close(struct gsm_bts_trx *trx) +{ + struct phy_instance *pinst = trx_phy_instance(trx); + struct phy_link *plink = pinst->phy_link; + struct octphy_hdl *fl1h = plink->u.octphy.hdl; + struct msgb *msg = l1p_msgb_alloc(); + tOCTVC1_GSM_MSG_TRX_CLOSE_CMD *cac; + + cac = (tOCTVC1_GSM_MSG_TRX_CLOSE_CMD *) + msgb_put(msg, sizeof(*cac)); + l1if_fill_msg_hdr(&cac->Header, msg, fl1h, cOCTVC1_MSG_TYPE_COMMAND, + cOCTVC1_GSM_MSG_TRX_CLOSE_CID); + + cac->TrxId.byTrxId = pinst->u.octphy.trx_id; + + LOGP(DL1C, LOGL_INFO, "Tx TRX-CLOSE.req(%u)\n", cac->TrxId.byTrxId); + + mOCTVC1_GSM_MSG_TRX_CLOSE_CMD_SWAP(cac); + + return l1if_req_compl(fl1h, msg, trx_close_cb, NULL); +} + /* call-back once the TRX_OPEN_CID response arrives */ -static int trx_open_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, void *data) +static int trx_open_compl_cb(struct octphy_hdl *fl1h, struct msgb *resp, void *data) { + struct gsm_bts_trx *trx; + tOCTVC1_GSM_MSG_TRX_OPEN_RSP *or = (tOCTVC1_GSM_MSG_TRX_OPEN_RSP *) resp->l2h; @@ -1203,8 +1255,7 @@ static int trx_open_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, void *d * release it before returning */ mOCTVC1_GSM_MSG_TRX_OPEN_RSP_SWAP(or); - - OSMO_ASSERT(or->TrxId.byTrxId == trx->nr); + trx = trx_by_l1h(fl1h, or->TrxId.byTrxId); LOGP(DL1C, LOGL_INFO, "TRX-OPEN.resp(trx=%u) = %s\n", trx->nr, octvc1_rc2string(or->Header.ulReturnCode)); @@ -1221,7 +1272,6 @@ static int trx_open_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, void *d opstart_compl(&trx->mo); - struct octphy_hdl *fl1h = trx_octphy_hdl(trx); octphy_hw_get_pcb_info(fl1h); octphy_hw_get_rf_port_info(fl1h, 0); octphy_hw_get_rf_ant_rx_config(fl1h, 0, 0); @@ -1238,22 +1288,24 @@ static int trx_open_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, void *d int l1if_trx_open(struct gsm_bts_trx *trx) { /* putting it all together */ - struct octphy_hdl *fl1h = trx_octphy_hdl(trx); + struct phy_instance *pinst = trx_phy_instance(trx); + struct phy_link *plink = pinst->phy_link; + struct octphy_hdl *fl1h = pinst->phy_link->u.octphy.hdl; struct msgb *msg = l1p_msgb_alloc(); tOCTVC1_GSM_MSG_TRX_OPEN_CMD *oc; oc = (tOCTVC1_GSM_MSG_TRX_OPEN_CMD *) msgb_put(msg, sizeof(*oc)); l1if_fill_msg_hdr(&oc->Header, msg, fl1h, cOCTVC1_MSG_TYPE_COMMAND, cOCTVC1_GSM_MSG_TRX_OPEN_CID); - oc->ulRfPortIndex = fl1h->config.rf_port_index; - oc->TrxId.byTrxId = trx->nr; + oc->ulRfPortIndex = plink->u.octphy.rf_port_index; + oc->TrxId.byTrxId = pinst->u.octphy.trx_id; oc->Config.ulBand = osmocom_to_octphy_band(trx->bts->band, trx->arfcn); oc->Config.usArfcn = trx->arfcn; oc->Config.usTsc = trx->bts->bsic & 0x7; oc->Config.usBcchArfcn = trx->bts->c0->arfcn; - oc->RfConfig.ulRxGainDb = fl1h->config.rx_gain_db; + oc->RfConfig.ulRxGainDb = plink->u.octphy.rx_gain_db; /* FIXME: compute this based on nominal transmit power, etc. */ - oc->RfConfig.ulTxAttndB = fl1h->config.tx_atten_db; + oc->RfConfig.ulTxAttndB = plink->u.octphy.tx_atten_db; LOGP(DL1C, LOGL_INFO, "Tx TRX-OPEN.req(trx=%u, rf_port=%u, arfcn=%u, " "tsc=%u, rx_gain=%u, tx_atten=%u)\n", @@ -1266,38 +1318,6 @@ int l1if_trx_open(struct gsm_bts_trx *trx) return l1if_req_compl(fl1h, msg, trx_open_compl_cb, NULL); } -static int trx_close_all_cb(struct gsm_bts_trx *trx, struct msgb *resp, void *data) -{ - tOCTVC1_GSM_MSG_TRX_CLOSE_ALL_RSP *car = - (tOCTVC1_GSM_MSG_TRX_CLOSE_ALL_RSP *) resp->l2h; - - /* in a completion call-back, we take msgb ownership and must - * release it before returning */ - - mOCTVC1_GSM_MSG_TRX_CLOSE_ALL_RSP_SWAP(car); - - msgb_free(resp); - - return 0; -} - -int l1if_trx_close_all(struct gsm_bts *bts) -{ - struct octphy_hdl *fl1h = trx_octphy_hdl(bts->c0); - struct msgb *msg = l1p_msgb_alloc(); - tOCTVC1_GSM_MSG_TRX_CLOSE_ALL_CMD *cac; - - cac = (tOCTVC1_GSM_MSG_TRX_CLOSE_ALL_CMD *) - msgb_put(msg, sizeof(*cac)); - l1if_fill_msg_hdr(&cac->Header, msg, fl1h, cOCTVC1_MSG_TYPE_COMMAND, - cOCTVC1_GSM_MSG_TRX_CLOSE_ALL_CID); - - mOCTVC1_GSM_MSG_TRX_CLOSE_ALL_CMD_SWAP(cac); - - return l1if_req_compl(fl1h, msg, trx_close_all_cb, NULL); -} - - uint32_t trx_get_hlayer1(struct gsm_bts_trx * trx) { return 0; @@ -1313,8 +1333,6 @@ static int trx_init(struct gsm_bts_trx *trx) /* return oml_mo_opstart_nack(&trx->mo, NM_NACK_CANT_PERFORM); */ } - l1if_trx_close_all(trx->bts); - l1if_check_app_version(trx); l1if_check_app_sys_version(trx); @@ -1325,11 +1343,12 @@ static int trx_init(struct gsm_bts_trx *trx) * PHYSICAL CHANNE ACTIVATION ***********************************************************************/ -static int pchan_act_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, void *data) +static int pchan_act_compl_cb(struct octphy_hdl *fl1, struct msgb *resp, void *data) { tOCTVC1_GSM_MSG_TRX_ACTIVATE_PHYSICAL_CHANNEL_RSP *ar = (tOCTVC1_GSM_MSG_TRX_ACTIVATE_PHYSICAL_CHANNEL_RSP *) resp->l2h; uint8_t ts_nr; + struct gsm_bts_trx *trx; struct gsm_bts_trx_ts *ts; struct gsm_abis_mo *mo; @@ -1337,9 +1356,8 @@ static int pchan_act_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, void * * release it before returning */ mOCTVC1_GSM_MSG_TRX_ACTIVATE_PHYSICAL_CHANNEL_RSP_SWAP(ar); + trx = trx_by_l1h(fl1, ar->TrxId.byTrxId); ts_nr = ar->PchId.byTimeslotNb; - - OSMO_ASSERT(ar->TrxId.byTrxId == trx->nr); OSMO_ASSERT(ts_nr <= ARRAY_SIZE(trx->ts)); ts = &trx->ts[ts_nr]; @@ -1367,7 +1385,8 @@ static int pchan_act_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, void * static int ts_connect(struct gsm_bts_trx_ts *ts) { - struct octphy_hdl *fl1h = trx_octphy_hdl(ts->trx); + struct phy_instance *pinst = trx_phy_instance(ts->trx); + struct octphy_hdl *fl1h = pinst->phy_link->u.octphy.hdl; struct msgb *msg = l1p_msgb_alloc(); tOCTVC1_GSM_MSG_TRX_ACTIVATE_PHYSICAL_CHANNEL_CMD *oc = (tOCTVC1_GSM_MSG_TRX_ACTIVATE_PHYSICAL_CHANNEL_CMD *) oc; @@ -1376,7 +1395,7 @@ static int ts_connect(struct gsm_bts_trx_ts *ts) l1if_fill_msg_hdr(&oc->Header, msg, fl1h, cOCTVC1_MSG_TYPE_COMMAND, cOCTVC1_GSM_MSG_TRX_ACTIVATE_PHYSICAL_CHANNEL_CID); - oc->TrxId.byTrxId = ts->trx->nr; + oc->TrxId.byTrxId = pinst->u.octphy.trx_id; oc->PchId.byTimeslotNb = ts->nr; oc->ulChannelType = pchan_to_logChComb[ts->pchan]; @@ -1430,8 +1449,7 @@ int bts_model_oml_estab(struct gsm_bts *bts) int i; for (i = 0; i < bts->num_trx; i++) { struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, i); - struct octphy_hdl *fl1h = trx_octphy_hdl(trx); - l1if_activate_rf(fl1h, 1); + l1if_activate_rf(trx, 1); } return 0; } @@ -1447,14 +1465,13 @@ int bts_model_chg_adm_state(struct gsm_bts *bts, struct gsm_abis_mo *mo, int bts_model_trx_deact_rf(struct gsm_bts_trx *trx) { - struct octphy_hdl *fl1 = trx_octphy_hdl(trx); - return l1if_activate_rf(fl1, 0); + return l1if_activate_rf(trx, 0); } int bts_model_trx_close(struct gsm_bts_trx *trx) { /* FIXME: close only one TRX */ - return l1if_trx_close_all(trx->bts); + return trx_close(trx); } diff --git a/src/osmo-bts-octphy/main.c b/src/osmo-bts-octphy/main.c index 1f516e4a..0f4d0dd4 100644 --- a/src/osmo-bts-octphy/main.c +++ b/src/osmo-bts-octphy/main.c @@ -52,10 +52,9 @@ extern int pcu_direct; -static struct gsm_bts *bts; - int bts_model_print_help() { + return 0; } int bts_model_handle_options(int argc, char **argv) diff --git a/src/osmo-bts-octphy/octphy_hw_api.c b/src/osmo-bts-octphy/octphy_hw_api.c index 5291742f..ec7c4be3 100644 --- a/src/osmo-bts-octphy/octphy_hw_api.c +++ b/src/osmo-bts-octphy/octphy_hw_api.c @@ -35,7 +35,7 @@ #include <octphy/octvc1/hw/octvc1_hw_api_swap.h> /* Chapter 12.1 */ -static int get_pcb_info_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, void *data) +static int get_pcb_info_compl_cb(struct octphy_hdl *fl1, struct msgb *resp, void *data) { tOCTVC1_HW_MSG_PCB_INFO_RSP *pir = (tOCTVC1_HW_MSG_PCB_INFO_RSP *) resp->l2h; @@ -69,7 +69,7 @@ int octphy_hw_get_pcb_info(struct octphy_hdl *fl1h) } /* Chapter 12.9 */ -static int rf_port_info_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, +static int rf_port_info_compl_cb(struct octphy_hdl *fl1, struct msgb *resp, void *data) { tOCTVC1_HW_MSG_RF_PORT_INFO_RSP *pir = @@ -114,7 +114,7 @@ static const struct value_string radio_std_vals[] = { }; /* Chapter 12.10 */ -static int rf_port_stats_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, +static int rf_port_stats_compl_cb(struct octphy_hdl *fl1, struct msgb *resp, void *data) { tOCTVC1_HW_MSG_RF_PORT_STATS_RSP *psr = @@ -167,7 +167,7 @@ static const struct value_string rx_gain_mode_vals[] = { }; /* Chapter 12.13 */ -static int rf_ant_rx_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, +static int rf_ant_rx_compl_cb(struct octphy_hdl *fl1, struct msgb *resp, void *data) { tOCTVC1_HW_MSG_RF_PORT_INFO_ANTENNA_RX_CONFIG_RSP *arc = @@ -209,7 +209,7 @@ int octphy_hw_get_rf_ant_rx_config(struct octphy_hdl *fl1h, uint32_t port_idx, } /* Chapter 12.14 */ -static int rf_ant_tx_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, +static int rf_ant_tx_compl_cb(struct octphy_hdl *fl1, struct msgb *resp, void *data) { tOCTVC1_HW_MSG_RF_PORT_INFO_ANTENNA_TX_CONFIG_RSP *atc = @@ -292,7 +292,7 @@ static const struct value_string clocksync_state_vals[] = { }; /* Chapter 12.15 */ -static int get_clock_sync_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, +static int get_clock_sync_compl_cb(struct octphy_hdl *fl1, struct msgb *resp, void *data) { tOCTVC1_HW_MSG_CLOCK_SYNC_MGR_INFO_RSP *cir = @@ -326,7 +326,7 @@ int octphy_hw_get_clock_sync_info(struct octphy_hdl *fl1h) } /* Chapter 12.16 */ -static int get_clock_sync_stats_cb(struct gsm_bts_trx *trx, struct msgb *resp, +static int get_clock_sync_stats_cb(struct octphy_hdl *fl1, struct msgb *resp, void *data) { tOCTVC1_HW_MSG_CLOCK_SYNC_MGR_STATS_RSP *csr = diff --git a/src/osmo-bts-octphy/octphy_vty.c b/src/osmo-bts-octphy/octphy_vty.c index dbc903a9..6e58ad42 100644 --- a/src/osmo-bts-octphy/octphy_vty.c +++ b/src/osmo-bts-octphy/octphy_vty.c @@ -38,6 +38,7 @@ #include <osmocom/vty/misc.h> #include <osmo-bts/gsm_data.h> +#include <osmo-bts/phy_link.h> #include <osmo-bts/logging.h> #include <osmo-bts/vty.h> @@ -51,149 +52,189 @@ SHOW_STR \ TRX_STR +#define OCT_STR "OCTPHY Um interface\n" + static struct gsm_bts *vty_bts; /* configuration */ -DEFUN(cfg_bts_phy_hwaddr, cfg_bts_phy_hwaddr_cmd, - "phy-hw-addr HWADDR", - "Configure the hardware addess of the OCTPHY\n" +DEFUN(cfg_phy_hwaddr, cfg_phy_hwaddr_cmd, + "octphy hw-addr HWADDR", + OCT_STR "Configure the hardware addess of the OCTPHY\n" "hardware address in aa:bb:cc:dd:ee:ff format\n") { - struct gsm_bts *bts = vty->index; - struct gsm_bts_trx *trx = bts->c0; - struct octphy_hdl *fl1h = trx_octphy_hdl(trx); + struct phy_link *plink = vty->index; int rc; - rc = osmo_macaddr_parse(fl1h->phy_addr.sll_addr, argv[0]); + if (plink->state != PHY_LINK_SHUTDOWN) { + vty_out(vty, "Can only reconfigure a PHY link that is down%s", + VTY_NEWLINE); + return CMD_WARNING; + } + + rc = osmo_macaddr_parse(plink->u.octphy.phy_addr.sll_addr, argv[0]); if (rc < 0) return CMD_WARNING; return CMD_SUCCESS; } -DEFUN(cfg_bts_phy_netdev, cfg_bts_phy_netdev_cmd, - "phy-netdev NAME", - "Configure the hardware device towards the OCTPHY\n" +DEFUN(cfg_phy_netdev, cfg_phy_netdev_cmd, + "octphy net-device NAME", + OCT_STR "Configure the hardware device towards the OCTPHY\n" "Ethernet device name\n") { - struct gsm_bts *bts = vty->index; - struct gsm_bts_trx *trx = bts->c0; - struct octphy_hdl *fl1h = trx_octphy_hdl(trx); + struct phy_link *plink = vty->index; - if (fl1h->netdev_name) - talloc_free(fl1h->netdev_name); - fl1h->netdev_name = talloc_strdup(fl1h, argv[0]); + if (plink->state != PHY_LINK_SHUTDOWN) { + vty_out(vty, "Can only reconfigure a PHY link that is down%s", + VTY_NEWLINE); + return CMD_WARNING; + } + + if (plink->u.octphy.netdev_name) + talloc_free(plink->u.octphy.netdev_name); + plink->u.octphy.netdev_name = talloc_strdup(plink, argv[0]); return CMD_SUCCESS; } -DEFUN(cfg_trx_rf_port_idx, cfg_trx_rf_port_idx_cmd, - "rf-port-index <0-255>", - "Configure the RF Port for this TRX\n" +DEFUN(cfg_phy_rf_port_idx, cfg_phy_rf_port_idx_cmd, + "octphy rf-port-index <0-255>", + OCT_STR "Configure the RF Port for this TRX\n" "RF Port Index\n") { - struct gsm_bts_trx *trx = vty->index; - struct octphy_hdl *fl1h = trx_octphy_hdl(trx); + struct phy_link *plink = vty->index; - fl1h->config.rf_port_index = atoi(argv[0]); + if (plink->state != PHY_LINK_SHUTDOWN) { + vty_out(vty, "Can only reconfigure a PHY link that is down%s", + VTY_NEWLINE); + return CMD_WARNING; + } + + plink->u.octphy.rf_port_index = atoi(argv[0]); return CMD_SUCCESS; } -DEFUN(cfg_trx_rx_gain_db, cfg_trx_rx_gain_db_cmd, - "rx-gain <0-73>", - "Configure the Rx Gain in dB\n" +DEFUN(cfg_phy_rx_gain_db, cfg_phy_rx_gain_db_cmd, + "octphy rx-gain <0-73>", + OCT_STR "Configure the Rx Gain in dB\n" "Rx gain in dB\n") { - struct gsm_bts_trx *trx = vty->index; - struct octphy_hdl *fl1h = trx_octphy_hdl(trx); + struct phy_link *plink = vty->index; + + if (plink->state != PHY_LINK_SHUTDOWN) { + vty_out(vty, "Can only reconfigure a PHY link that is down%s", + VTY_NEWLINE); + return CMD_WARNING; + } - fl1h->config.rx_gain_db = atoi(argv[0]); + plink->u.octphy.rx_gain_db = atoi(argv[0]); return CMD_SUCCESS; } -DEFUN(cfg_trx_tx_atten_db, cfg_trx_tx_atten_db_cmd, - "tx-attenuation <0-359>", - "Configure the Tx Attenuation in quarter-dB\n" +DEFUN(cfg_phy_tx_atten_db, cfg_phy_tx_atten_db_cmd, + "octphy tx-attenuation <0-359>", + OCT_STR "Configure the Tx Attenuation in quarter-dB\n" "Tx attenuation in quarter-dB\n") { - struct gsm_bts_trx *trx = vty->index; - struct octphy_hdl *fl1h = trx_octphy_hdl(trx); + struct phy_link *plink = vty->index; + + if (plink->state != PHY_LINK_SHUTDOWN) { + vty_out(vty, "Can only reconfigure a PHY link that is down%s", + VTY_NEWLINE); + return CMD_WARNING; + } - fl1h->config.tx_atten_db = atoi(argv[0]); + plink->u.octphy.tx_atten_db = atoi(argv[0]); return CMD_SUCCESS; } -DEFUN(get_rf_port_stats, get_rf_port_stats_cmd, - "get-rf-port-stats <0-1>", - "Obtain statistics for the RF Port\n" +DEFUN(show_rf_port_stats, show_rf_port_stats_cmd, + "show phy <0-255> rf-port-stats <0-1>", + "Show statistics for the RF Port\n" "RF Port Number\n") { - struct octphy_hdl *fl1h = trx_octphy_hdl(vty_bts->c0); + int phy_nr = atoi(argv[0]); + struct phy_link *plink = phy_link_by_num(phy_nr); - octphy_hw_get_rf_port_stats(fl1h, atoi(argv[0])); + octphy_hw_get_rf_port_stats(plink->u.octphy.hdl, atoi(argv[1])); + + /* FIXME: Actually print to VTY, not just log */ + vty_out(vty, "Please check the log file for the response%s", + VTY_NEWLINE); return CMD_SUCCESS; } -DEFUN(get_clk_sync_stats, get_clk_sync_stats_cmd, - "get-clk-sync-stats", +DEFUN(show_clk_sync_stats, show_clk_sync_stats_cmd, + "show phy <0-255> clk-sync-stats", "Obtain statistics for the Clock Sync Manager\n") { - struct octphy_hdl *fl1h = trx_octphy_hdl(vty_bts->c0); + int phy_nr = atoi(argv[0]); + struct phy_link *plink = phy_link_by_num(phy_nr); + + octphy_hw_get_clock_sync_stats(plink->u.octphy.hdl); - octphy_hw_get_clock_sync_stats(fl1h); + /* FIXME: Actually print to VTY, not just log */ + vty_out(vty, "Please check the log file for the response%s", + VTY_NEWLINE); return CMD_SUCCESS; } +void bts_model_config_write_phy(struct vty *vty, struct phy_link *plink) +{ + if (plink->u.octphy.netdev_name) + vty_out(vty, " netdev %s%s", plink->u.octphy.netdev_name, + VTY_NEWLINE); + + vty_out(vty, " hw-addr %02x:%02x:%02x:%02x:%02x:%02x%s", + plink->u.octphy.phy_addr.sll_addr[0], + plink->u.octphy.phy_addr.sll_addr[1], + plink->u.octphy.phy_addr.sll_addr[2], + plink->u.octphy.phy_addr.sll_addr[3], + plink->u.octphy.phy_addr.sll_addr[4], + plink->u.octphy.phy_addr.sll_addr[5], + VTY_NEWLINE); + vty_out(vty, " rx-gain %u%s", plink->u.octphy.rx_gain_db, + VTY_NEWLINE); + vty_out(vty, " tx-attenuation %u%s", plink->u.octphy.tx_atten_db, + VTY_NEWLINE); + vty_out(vty, " rf-port-index %u%s", plink->u.octphy.rf_port_index, + VTY_NEWLINE); +} + void bts_model_config_write_bts(struct vty *vty, struct gsm_bts *bts) { struct gsm_bts_role_bts *btsb = bts_role_bts(bts); - struct octphy_hdl *fl1h = trx_octphy_hdl(bts->c0); - - if (fl1h->netdev_name) - vty_out(vty, " phy-netdev %s%s", fl1h->netdev_name, - VTY_NEWLINE); if (btsb->auto_band) vty_out(vty, " auto-band%s", VTY_NEWLINE); - vty_out(vty, " phy-hw-addr %02x:%02x:%02x:%02x:%02x:%02x%s", - fl1h->phy_addr.sll_addr[0], fl1h->phy_addr.sll_addr[1], - fl1h->phy_addr.sll_addr[2], fl1h->phy_addr.sll_addr[3], - fl1h->phy_addr.sll_addr[4], fl1h->phy_addr.sll_addr[5], - VTY_NEWLINE); } void bts_model_config_write_trx(struct vty *vty, struct gsm_bts_trx *trx) { - struct octphy_hdl *fl1h = trx_octphy_hdl(trx); - - vty_out(vty, " rx-gain %u%s", fl1h->config.rx_gain_db, - VTY_NEWLINE); - vty_out(vty, " tx-attenuation %u%s", fl1h->config.tx_atten_db, - VTY_NEWLINE); } DEFUN(show_sys_info, show_sys_info_cmd, - "show trx <0-255> system-information", + "show phy <0-255> system-information", SHOW_TRX_STR "Display information about system\n") { - int trx_nr = atoi(argv[0]); - struct gsm_bts_trx *trx = gsm_bts_trx_num(vty_bts, trx_nr); + int phy_nr = atoi(argv[0]); + struct phy_link *plink = phy_link_by_num(phy_nr); struct octphy_hdl *fl1h; - int i; - if (!trx) { - vty_out(vty, "Cannot find TRX number %u%s", - trx_nr, VTY_NEWLINE); + if (!plink) { + vty_out(vty, "Cannot find PHY number %u%s", + phy_nr, VTY_NEWLINE); return CMD_WARNING; } - fl1h = trx_octphy_hdl(trx); + fl1h = plink->u.octphy.hdl; vty_out(vty, "System Platform: '%s', Version: '%s'%s", fl1h->info.system.platform, fl1h->info.system.version, @@ -210,15 +251,14 @@ int bts_model_vty_init(struct gsm_bts *bts) { vty_bts = bts; - install_element(BTS_NODE, &cfg_bts_phy_hwaddr_cmd); - install_element(BTS_NODE, &cfg_bts_phy_netdev_cmd); + install_element(PHY_NODE, &cfg_phy_hwaddr_cmd); + install_element(PHY_NODE, &cfg_phy_netdev_cmd); + install_element(PHY_NODE, &cfg_phy_rf_port_idx_cmd); + install_element(PHY_NODE, &cfg_phy_rx_gain_db_cmd); + install_element(PHY_NODE, &cfg_phy_tx_atten_db_cmd); - install_element(TRX_NODE, &cfg_trx_rf_port_idx_cmd); - install_element(TRX_NODE, &cfg_trx_rx_gain_db_cmd); - install_element(TRX_NODE, &cfg_trx_tx_atten_db_cmd); - - install_element_ve(&get_rf_port_stats_cmd); - install_element_ve(&get_clk_sync_stats_cmd); + install_element_ve(&show_rf_port_stats_cmd); + install_element_ve(&show_clk_sync_stats_cmd); install_element_ve(&show_sys_info_cmd); return 0; @@ -226,13 +266,5 @@ int bts_model_vty_init(struct gsm_bts *bts) int bts_model_ctrl_cmds_install(struct gsm_bts *bts) { - /* FIXME: really ugly hack: We can only initialize the L1 intrface - * after reading the config file, and this is the only call-back after - * vty_read_config_fioe() at this point. Will be cleaned up with the - * phy interface generalization patches coming up soon as part of the - * multi-trx work */ - struct octphy_hdl *fl1h = bts->c0->role_bts.l1h; - l1if_open(fl1h); - return 0; } |