trxcon/l1sched: trigger sending UL BLOCK.cnf for PDTCH
In tx_pdtch_fn(), delay sending DATA.cnf until bid=3. Otherwise we send it too early (at bid=0) and trick the upper layers (RLC/MAC) to believe that the whole block (all bursts) has been transmitted. Change-Id: If32fafeef0ea347ed3800e6b67349bf12e66047f
This commit is contained in:
parent
8da604cfb3
commit
c5f93fc2c2
|
@ -223,6 +223,8 @@ struct l1sched_lchan_state {
|
||||||
|
|
||||||
/*! Queue of Tx primitives */
|
/*! Queue of Tx primitives */
|
||||||
struct llist_head tx_prims;
|
struct llist_head tx_prims;
|
||||||
|
/*! Tx primitive being sent */
|
||||||
|
struct msgb *prim;
|
||||||
|
|
||||||
/*! Mode for TCH channels (see GSM48_CMODE_*) */
|
/*! Mode for TCH channels (see GSM48_CMODE_*) */
|
||||||
uint8_t tch_mode;
|
uint8_t tch_mode;
|
||||||
|
|
|
@ -105,6 +105,8 @@ struct trxcon_param_tx_data_cnf {
|
||||||
uint8_t link_id;
|
uint8_t link_id;
|
||||||
uint16_t band_arfcn;
|
uint16_t band_arfcn;
|
||||||
uint32_t frame_nr;
|
uint32_t frame_nr;
|
||||||
|
size_t data_len;
|
||||||
|
const uint8_t *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* param of TRXCON_EV_RX_DATA_IND */
|
/* param of TRXCON_EV_RX_DATA_IND */
|
||||||
|
|
|
@ -160,8 +160,9 @@ int tx_pdtch_fn(struct l1sched_lchan_state *lchan,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Confirm data / traffic sending (pass ownership of the msgb/prim) */
|
/* Cache the prim, so that we can confirm it later (see below) */
|
||||||
l1sched_lchan_emit_data_cnf(lchan, msg, br->fn);
|
OSMO_ASSERT(lchan->prim == NULL);
|
||||||
|
lchan->prim = msg;
|
||||||
|
|
||||||
send_burst:
|
send_burst:
|
||||||
/* Determine which burst should be sent */
|
/* Determine which burst should be sent */
|
||||||
|
@ -183,5 +184,12 @@ send_burst:
|
||||||
|
|
||||||
LOGP_LCHAND(lchan, LOGL_DEBUG, "Scheduled at fn=%u burst=%u\n", br->fn, br->bid);
|
LOGP_LCHAND(lchan, LOGL_DEBUG, "Scheduled at fn=%u burst=%u\n", br->fn, br->bid);
|
||||||
|
|
||||||
|
if (br->bid == 3) {
|
||||||
|
/* Confirm data / traffic sending (pass ownership of the msgb/prim) */
|
||||||
|
l1sched_lchan_emit_data_cnf(lchan, lchan->prim,
|
||||||
|
GSM_TDMA_FN_SUB(br->fn, 3));
|
||||||
|
lchan->prim = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -610,6 +610,18 @@ static void trxcon_st_packet_data_action(struct osmo_fsm_inst *fi,
|
||||||
l1sched_prim_from_user(trxcon->sched, msg);
|
l1sched_prim_from_user(trxcon->sched, msg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case TRXCON_EV_TX_DATA_CNF:
|
||||||
|
{
|
||||||
|
const struct trxcon_param_tx_data_cnf *cnf = data;
|
||||||
|
struct msgb *msg;
|
||||||
|
|
||||||
|
msg = l1gprs_handle_ul_block_cnf(trxcon->gprs,
|
||||||
|
cnf->frame_nr, cnf->chan_nr & 0x07,
|
||||||
|
cnf->data, cnf->data_len);
|
||||||
|
if (msg != NULL)
|
||||||
|
trxcon_l1ctl_send(trxcon, msg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case TRXCON_EV_RX_DATA_IND:
|
case TRXCON_EV_RX_DATA_IND:
|
||||||
{
|
{
|
||||||
const struct trxcon_param_rx_data_ind *ind = data;
|
const struct trxcon_param_rx_data_ind *ind = data;
|
||||||
|
@ -655,8 +667,6 @@ static void trxcon_st_packet_data_action(struct osmo_fsm_inst *fi,
|
||||||
l1sched_reset(trxcon->sched, false);
|
l1sched_reset(trxcon->sched, false);
|
||||||
/* TODO: switch to (not implemented) TRXCON_ST_DCH_TUNING? */
|
/* TODO: switch to (not implemented) TRXCON_ST_DCH_TUNING? */
|
||||||
break;
|
break;
|
||||||
case TRXCON_EV_TX_DATA_CNF:
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
OSMO_ASSERT(0);
|
OSMO_ASSERT(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,6 +102,8 @@ static int handle_prim_data_cnf(struct trxcon_inst *trxcon, struct msgb *msg)
|
||||||
.link_id = prim->data_cnf.link_id,
|
.link_id = prim->data_cnf.link_id,
|
||||||
.band_arfcn = trxcon->l1p.band_arfcn,
|
.band_arfcn = trxcon->l1p.band_arfcn,
|
||||||
.frame_nr = prim->data_cnf.frame_nr,
|
.frame_nr = prim->data_cnf.frame_nr,
|
||||||
|
.data_len = msgb_l2len(msg),
|
||||||
|
.data = msgb_l2(msg),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (trxcon->gsmtap != NULL) {
|
if (trxcon->gsmtap != NULL) {
|
||||||
|
|
Loading…
Reference in New Issue