aboutsummaryrefslogtreecommitdiffstats
path: root/src/gprs_rlcmac_sched.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gprs_rlcmac_sched.cpp')
-rw-r--r--src/gprs_rlcmac_sched.cpp78
1 files changed, 32 insertions, 46 deletions
diff --git a/src/gprs_rlcmac_sched.cpp b/src/gprs_rlcmac_sched.cpp
index 8867d436..ac581216 100644
--- a/src/gprs_rlcmac_sched.cpp
+++ b/src/gprs_rlcmac_sched.cpp
@@ -11,10 +11,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <gprs_bssgp_pcu.h>
@@ -32,6 +28,7 @@
extern "C" {
#include <osmocom/core/gsmtap.h>
+ #include "nacc_fsm.h"
}
struct tbf_sched_candidates {
@@ -49,35 +46,27 @@ static void get_ctrl_msg_tbf_candidates(const struct gprs_rlcmac_pdch *pdch,
struct llist_item *pos;
llist_for_each_entry(pos, &pdch->trx->ul_tbfs, list) {
- ul_tbf = as_ul_tbf((struct gprs_rlcmac_tbf *)pos->entry);
+ ul_tbf = tbf_as_ul_tbf((struct gprs_rlcmac_tbf *)pos->entry);
OSMO_ASSERT(ul_tbf);
- /* this trx, this ts */
- if (!ul_tbf->is_control_ts(pdch->ts_no))
- continue;
- if (tbf_ul_ack_rts(ul_tbf))
+ if (tbf_ul_ack_rts(ul_tbf, pdch))
tbf_cand->ul_ack = ul_tbf;
- if (tbf_dl_ass_rts(ul_tbf))
+ if (tbf_dl_ass_rts(ul_tbf, pdch))
tbf_cand->dl_ass = ul_tbf;
- if (tbf_ul_ass_rts(ul_tbf))
+ if (tbf_ul_ass_rts(ul_tbf, pdch))
tbf_cand->ul_ass = ul_tbf;
- /* NACC ready to send. TFI assigned is needed to send messages */
- if (ul_tbf->is_tfi_assigned() && ms_nacc_rts(ul_tbf->ms()))
+ if (tbf_nacc_rts(ul_tbf, pdch))
tbf_cand->nacc = ul_tbf;
/* FIXME: Is this supposed to be fair? The last TBF for each wins? Maybe use llist_add_tail and skip once we have all
states? */
}
llist_for_each_entry(pos, &pdch->trx->dl_tbfs, list) {
- dl_tbf = as_dl_tbf((struct gprs_rlcmac_tbf *)pos->entry);
+ dl_tbf = tbf_as_dl_tbf((struct gprs_rlcmac_tbf *)pos->entry);
OSMO_ASSERT(dl_tbf);
- /* this trx, this ts */
- if (!dl_tbf->is_control_ts(pdch->ts_no))
- continue;
- if (tbf_dl_ass_rts(dl_tbf))
+ if (tbf_dl_ass_rts(dl_tbf, pdch))
tbf_cand->dl_ass = dl_tbf;
- if (tbf_ul_ass_rts(dl_tbf))
+ if (tbf_ul_ass_rts(dl_tbf, pdch))
tbf_cand->ul_ass = dl_tbf;
- /* NACC ready to send. TFI assigned is needed to send messages */
- if (dl_tbf->is_tfi_assigned() && ms_nacc_rts(dl_tbf->ms()))
+ if (tbf_nacc_rts(dl_tbf, pdch))
tbf_cand->nacc = dl_tbf;
}
}
@@ -150,7 +139,6 @@ static struct msgb *sched_select_ctrl_msg(struct gprs_rlcmac_pdch *pdch, uint32_
tbfs->dl_ass,
tbfs->ul_ack,
tbfs->nacc };
- uint8_t ts = pdch->ts_no;
/* Send Packet Application Information first (ETWS primary notifications) */
msg = sched_app_info(tbfs->dl_ass);
@@ -167,16 +155,15 @@ static struct msgb *sched_select_ctrl_msg(struct gprs_rlcmac_pdch *pdch, uint32_
* received, thus preventing the others from being processed.
*/
if (tbf == tbfs->ul_ass && tbf->ul_ass_state_is(TBF_UL_ASS_SEND_ASS_REJ))
- msg = tbf_ul_ass_create_rlcmac_msg(tbfs->ul_ass, fn, ts);
+ msg = tbf_ul_ass_create_rlcmac_msg(tbfs->ul_ass, pdch, fn);
else if (tbf == tbfs->ul_ass && tbf->direction == GPRS_RLCMAC_DL_TBF)
- msg = tbf_ul_ass_create_rlcmac_msg(tbfs->ul_ass, fn, ts);
+ msg = tbf_ul_ass_create_rlcmac_msg(tbfs->ul_ass, pdch, fn);
else if (tbf == tbfs->dl_ass && tbf->direction == GPRS_RLCMAC_UL_TBF)
- msg = tbf_dl_ass_create_rlcmac_msg(tbfs->dl_ass, fn, ts);
+ msg = tbf_dl_ass_create_rlcmac_msg(tbfs->dl_ass, pdch, fn);
else if (tbf == tbfs->ul_ack)
- msg = tbf_ul_ack_create_rlcmac_msg(tbfs->ul_ack, fn, ts);
- else if (tbf == tbfs->nacc) {
- msg = ms_nacc_create_rlcmac_msg(tbf->ms(), tbf, fn, ts);
- }
+ msg = tbf_ul_ack_create_rlcmac_msg(tbfs->ul_ack, pdch, fn);
+ else if (tbf == tbfs->nacc)
+ msg = ms_nacc_create_rlcmac_msg(tbf->ms(), tbf, pdch, fn);
if (!msg) {
tbf = NULL;
@@ -196,10 +183,10 @@ static struct msgb *sched_select_ctrl_msg(struct gprs_rlcmac_pdch *pdch, uint32_
*/
if (tbfs->dl_ass) {
tbf = tbfs->dl_ass;
- msg = tbf_dl_ass_create_rlcmac_msg(tbfs->dl_ass, fn, ts);
+ msg = tbf_dl_ass_create_rlcmac_msg(tbfs->dl_ass, pdch, fn);
} else if (tbfs->ul_ass) {
tbf = tbfs->ul_ass;
- msg = tbf_ul_ass_create_rlcmac_msg(tbfs->ul_ass, fn, ts);
+ msg = tbf_ul_ass_create_rlcmac_msg(tbfs->ul_ass, pdch, fn);
}
}
@@ -231,24 +218,25 @@ static struct msgb *sched_select_ctrl_msg(struct gprs_rlcmac_pdch *pdch, uint32_
}
static inline enum tbf_dl_prio tbf_compute_priority(const struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_dl_tbf *tbf,
- uint8_t ts, uint32_t fn, int age)
+ const struct gprs_rlcmac_pdch *pdch, uint32_t fn, int age)
{
const gprs_rlc_dl_window *w = static_cast<gprs_rlc_dl_window *>(tbf->window());
unsigned long msecs_t3190 = osmo_tdef_get(the_pcu->T_defs, 3190, OSMO_TDEF_MS, -1);
unsigned long dl_tbf_idle_msec = osmo_tdef_get(the_pcu->T_defs, -2031, OSMO_TDEF_MS, -1);
int age_thresh1 = msecs_to_frames(200);
int age_thresh2 = msecs_to_frames(OSMO_MIN(msecs_t3190/2, dl_tbf_idle_msec));
+ const bool is_control_ts = tbf_is_control_ts(tbf, pdch);
- if (tbf->is_control_ts(ts) && tbf->need_poll_for_dl_ack_nack())
+ if (is_control_ts && tbf->need_poll_for_dl_ack_nack())
return DL_PRIO_CONTROL;
- if (tbf->is_control_ts(ts) && age > age_thresh2 && age_thresh2 > 0)
+ if (is_control_ts && age > age_thresh2 && age_thresh2 > 0)
return DL_PRIO_HIGH_AGE;
if ((tbf->state_is(TBF_ST_FLOW) && tbf->have_data()) || w->resend_needed() >= 0)
return DL_PRIO_NEW_DATA;
- if (tbf->is_control_ts(ts) && age > age_thresh1 && tbf->keep_open(fn))
+ if (is_control_ts && age > age_thresh1 && tbf->keep_open(fn))
return DL_PRIO_LOW_AGE;
if (!w->window_empty())
@@ -289,7 +277,6 @@ static struct msgb *sched_select_dl_data_msg(struct gprs_rlcmac_bts *bts, struct
struct msgb *msg = NULL;
struct gprs_rlcmac_dl_tbf *tbf, *prio_tbf = NULL;
enum tbf_dl_prio prio, max_prio = DL_PRIO_NONE;
- uint8_t ts = pdch->ts_no;
uint8_t i, tfi, prio_tfi;
int age;
@@ -316,7 +303,7 @@ static struct msgb *sched_select_dl_data_msg(struct gprs_rlcmac_bts *bts, struct
age = tbf->frames_since_last_poll(fn);
/* compute priority */
- prio = tbf_compute_priority(bts, tbf, ts, fn, age);
+ prio = tbf_compute_priority(bts, tbf, pdch, fn, age);
if (prio == DL_PRIO_NONE)
continue;
@@ -345,7 +332,7 @@ static struct msgb *sched_select_dl_data_msg(struct gprs_rlcmac_bts *bts, struct
/* next TBF to handle resource is the next one */
pdch->next_dl_tfi = (prio_tfi + 1) & 31;
/* generate DL data block */
- msg = prio_tbf->create_dl_acked_block(fn, ts, req_mcs_kind);
+ msg = prio_tbf->create_dl_acked_block(fn, pdch, req_mcs_kind);
*is_egprs = prio_tbf->is_egprs_enabled();
}
@@ -460,8 +447,8 @@ int gprs_rlcmac_rcv_rts_block(struct gprs_rlcmac_bts *bts,
* let's set its USF in the DL msg. This is not really needed,
* but it helps understand better the flow when looking at
* pcaps. */
- if (poll_tbf->direction == GPRS_RLCMAC_UL_TBF && as_ul_tbf(poll_tbf)->m_usf[ts] != USF_INVALID)
- usf_tbf = as_ul_tbf(poll_tbf);
+ if (poll_tbf->direction == GPRS_RLCMAC_UL_TBF && tbf_as_ul_tbf(poll_tbf)->m_usf[ts] != USF_INVALID)
+ usf_tbf = tbf_as_ul_tbf(poll_tbf);
/* else, search for uplink tbf */
} else if ((usf_tbf = sched_select_uplink(pdch, require_gprs_only))) {
LOGPDCH(pdch, DRLCMACSCHED, LOGL_DEBUG, "Received RTS for PDCH: FN=%d "
@@ -478,7 +465,7 @@ int gprs_rlcmac_rcv_rts_block(struct gprs_rlcmac_bts *bts,
/* Prio 1: select control message */
if ((msg = sched_select_ctrl_msg(pdch, fn, block_nr, &tbf_cand))) {
- gsmtap_cat = PCU_GSMTAP_C_DL_CTRL;
+ gsmtap_cat = PCU_GSMTAP_C_DL_CTRL;
}
/* Prio 2: select data message for downlink */
else if((msg = sched_select_dl_data_msg(bts, pdch, fn, block_nr, req_mcs_kind, &tx_is_egprs))) {
@@ -500,11 +487,10 @@ int gprs_rlcmac_rcv_rts_block(struct gprs_rlcmac_bts *bts,
const unsigned num_tbfs = pdch->num_tbfs(GPRS_RLCMAC_DL_TBF)
+ pdch->num_tbfs(GPRS_RLCMAC_UL_TBF);
bool skip_idle = (num_tbfs == 0);
-#ifdef ENABLE_DIRECT_PHY
- /* In DIRECT_PHY mode we want to always submit something to L1 in
- * TRX0, since BTS is not preparing dummy bursts on idle TS for us */
- skip_idle = skip_idle && trx != 0;
-#endif
+
+ if (bts->gen_idle_blocks_C0)
+ skip_idle = skip_idle && trx != 0;
+
if (!skip_idle && (msg = sched_dummy())) {
/* increase counter */
gsmtap_cat = PCU_GSMTAP_C_DL_DUMMY;