aboutsummaryrefslogtreecommitdiffstats
path: root/include/osmo-bts/phy_link.h
blob: 4b8a86335b0ca206fb3f315b72611e6fb50888a7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#pragma once

#include <stdint.h>
#include <stdbool.h>
#include <osmocom/core/linuxlist.h>

#include <osmo-bts/scheduler.h>
#include <osmo-bts/bts_trx.h>

#include <linux/if_packet.h>
#include "btsconfig.h"


struct virt_um_inst;

enum phy_link_type {
	PHY_LINK_T_NONE,
	PHY_LINK_T_SYSMOBTS,
	PHY_LINK_T_OSMOTRX,
	PHY_LINK_T_VIRTUAL,
};

enum phy_link_state {
	PHY_LINK_SHUTDOWN,
	PHY_LINK_CONNECTING,
	PHY_LINK_CONNECTED,
};

/* A PHY link represents the connection to a given PHYsical layer
 * implementation.  That PHY link contains 1...N PHY instances, one for
 * each TRX */
struct phy_link {
	struct llist_head list;
	int num;
	enum phy_link_type type;
	enum phy_link_state state;
	struct llist_head instances;
	char *description;
	union {
		struct {
		} sysmobts;
		struct {
			char *local_ip;
			char *remote_ip;
			uint16_t base_port_local;
			uint16_t base_port_remote;
			struct osmo_fd trx_ofd_clk;
			uint32_t clock_advance;
			uint32_t rts_advance;
			bool use_legacy_setbsic;
			uint8_t trxd_pdu_ver_max; /* Maximum TRXD PDU version to negotiate */
			bool powered; /* last POWERON (true) or POWEROFF (false) confirmed */
			bool poweronoff_sent; /* is there a POWERON/POWEROFF in transit? (one or the other based on ->powered) */
		} osmotrx;
		struct {
			char *mcast_dev;		/* Network device for multicast */
			int ttl;			/* TTL of transmitted udp multicast */
			char *bts_mcast_group;		/* BTS are listening to this group */
			uint16_t bts_mcast_port;
			char *ms_mcast_group;		/* MS are listening to this group */
			uint16_t ms_mcast_port;
			struct virt_um_inst *virt_um;
		} virt;
		struct {
			/* MAC address of the PHY */
			struct sockaddr_ll phy_addr;
			/* Network device name */
			char *netdev_name;

			/* configuration */
			uint32_t rf_port_index;
#if OCTPHY_USE_ANTENNA_ID == 1
			uint32_t rx_ant_id;
			uint32_t tx_ant_id;
#endif
			uint32_t rx_gain_db;
			bool tx_atten_flag;
			uint32_t tx_atten_db;
			bool over_sample_16x;
#if OCTPHY_MULTI_TRX == 1
			/* arfcn used by TRX with id 0 */
			uint16_t center_arfcn;
#endif

			struct octphy_hdl *hdl;
		} octphy;
	} u;
};

struct phy_instance {
	/* liked inside phy_link.linstances */
	struct llist_head list;
	int num;
	char *description;
	char version[MAX_VERSION_LENGTH];
	/* pointer to the PHY link to which we belong */
	struct phy_link *phy_link;

	/* back-pointer to the TRX to which we're associated */
	struct gsm_bts_trx *trx; /* NOTE: may be NULL! */

	union {
		struct {
			/* configuration */
			uint8_t clk_use_eeprom;
			uint32_t dsp_trace_f;
			int clk_cal;
			uint8_t clk_src;
			char *calib_path;

			struct femtol1_hdl *hdl;
		} sysmobts;
		struct {
			struct trx_l1h *hdl;
			bool sw_act_reported;
			struct trx_dl_burst_req br[TRX_NR_TS];
		} osmotrx;
		struct {
			/* logical transceiver number within one PHY */
			uint32_t trx_id;
			/* trx lock state variable */
			int trx_locked;
		} octphy;
		struct {
			/* configuration */
			uint32_t dsp_trace_f;
			char *calib_path;
			int minTxPower;
			int maxTxPower;
			struct lc15l1_hdl *hdl;
			uint8_t max_cell_size;		/* 0:166 qbits*/
			uint8_t diversity_mode;		/* 0: SISO A, 1: SISO B, 2: MRC */
			uint8_t pedestal_mode;		/* 0: unused TS is OFF, 1: unused TS is in minimum Tx power */
			uint8_t dsp_alive_period;	/* DSP alive timer period  */
			uint8_t tx_pwr_adj_mode;	/* 0: no auto adjust power, 1: auto adjust power using RMS detector */
			uint8_t tx_pwr_red_8psk;	/* 8-PSK maximum Tx power reduction level in dB */
			uint8_t tx_c0_idle_pwr_red;	/* C0 idle slot Tx power reduction level in dB */
		} lc15;
                struct {
                        /* configuration */
                        uint32_t dsp_trace_f;
                        char *calib_path;
                        int minTxPower;
                        int maxTxPower;
                        struct oc2gl1_hdl *hdl;
                        uint8_t max_cell_size;          /* 0:166 qbits*/
                        uint8_t pedestal_mode;          /* 0: unused TS is OFF, 1: unused TS is in minimum Tx power */
                        uint8_t dsp_alive_period;       /* DSP alive timer period  */
                        uint8_t tx_pwr_adj_mode;        /* 0: no auto adjust power, 1: auto adjust power using RMS detector */
                        uint8_t tx_pwr_red_8psk;        /* 8-PSK maximum Tx power reduction level in dB */
                        uint8_t tx_c0_idle_pwr_red;     /* C0 idle slot Tx power reduction level in dB */
                } oc2g;
	} u;
};

struct phy_link *phy_link_by_num(int num);
struct phy_link *phy_link_create(void *ctx, int num);
void phy_link_destroy(struct phy_link *plink);
const char *phy_link_name(const struct phy_link *plink);
void phy_link_state_set(struct phy_link *plink, enum phy_link_state state);
enum phy_link_state phy_link_state_get(struct phy_link *plink);
const char *phy_link_state_name(enum phy_link_state state);
int phy_links_open(void);

struct phy_instance *phy_instance_by_num(const struct phy_link *plink, int num);
struct phy_instance *phy_instance_create(struct phy_link *plink, int num);
void phy_instance_link_to_trx(struct phy_instance *pinst, struct gsm_bts_trx *trx);
void phy_instance_destroy(struct phy_instance *pinst);
const char *phy_instance_name(const struct phy_instance *pinst);

static inline struct phy_instance *trx_phy_instance(const struct gsm_bts_trx *trx)
{
	OSMO_ASSERT(trx);
	return trx->pinst;
}

int bts_model_phy_link_open(struct phy_link *plink);

#define LOGPPHL(plink, section, lvl, fmt, args...) LOGP(section, lvl, "%s: " fmt, phy_link_name(plink), ##args)
#define LOGPPHI(pinst, section, lvl, fmt, args...) LOGP(section, lvl, "%s: " fmt, phy_instance_name(pinst), ##args)