platform: msm_shared: Update G-Link with latest port
Add features related to G-Link QoS.
P4 Changelist: 8336849
Change-Id: Id9d95f9935f3d69e135d8dec32c5e8166ce5dffd
diff --git a/platform/msm_shared/glink/glink_api.c b/platform/msm_shared/glink/glink_api.c
index e693c8b..ab13442 100644
--- a/platform/msm_shared/glink/glink_api.c
+++ b/platform/msm_shared/glink/glink_api.c
@@ -131,6 +131,7 @@
ASSERT( open_ch_ctx->local_state == GLINK_LOCAL_CH_CLOSED );
glink_os_cs_init( &ch_ctx->tx_cs );
+ glink_os_cs_init(&ch_ctx->qos_cs);
glink_os_cs_init( &ch_ctx->ch_state_cs );
ch_ctx->rcid = open_ch_ctx->rcid;
@@ -138,6 +139,11 @@
ch_ctx->pintents = open_ch_ctx->pintents;
ch_ctx->if_ptr = open_ch_ctx->if_ptr;
+ if (ch_ctx->pintents != NULL)
+ {
+ ch_ctx->pintents->ch_ctx = ch_ctx;
+ }
+
ch_ctx->remote_state = open_ch_ctx->remote_state;
ch_ctx->local_state = GLINK_LOCAL_CH_OPENING;
@@ -161,7 +167,8 @@
{
/* REMOTE OPEN REQUEST */
- if( open_ch_ctx->remote_state == GLINK_REMOTE_CH_SSR_RESET )
+ if( open_ch_ctx->remote_state == GLINK_REMOTE_CH_SSR_RESET ||
+ open_ch_ctx->remote_state == GLINK_REMOTE_CH_CLEANUP)
{
/* During SSR previous channel ctx needs to be destroyed
* new remote/local open request will create new context */
@@ -209,6 +216,14 @@
ASSERT( open_ch_ctx == NULL );
+ /* check if a new channel can be added */
+ if ((uint32)smem_list_count(&if_ptr->glink_core_priv->open_list) >= xport_ctx->max_lcid)
+ {
+ glink_os_cs_release(&xport_ctx->channel_q_cs);
+ glink_os_free(ch_ctx);
+ return GLINK_STATUS_OUT_OF_RESOURCES;
+ }
+
/* Channel not in the list - it was not previously opened */
ch_ctx->if_ptr = if_ptr;
*allocated_ch_ctx = ch_ctx;
@@ -225,11 +240,33 @@
}
glink_os_cs_init(&ch_ctx->tx_cs);
+ glink_os_cs_init(&ch_ctx->qos_cs);
glink_os_cs_init(&ch_ctx->ch_state_cs);
- /* Append the channel to the transport interface's open_list */
- ch_ctx->lcid = xport_ctx->free_lcid;
+ /* make sure next LCID is not used in currently open channels */
+ open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
+
+ while (open_ch_ctx)
+ {
+ if (open_ch_ctx->lcid == xport_ctx->free_lcid)
+ {
xport_ctx->free_lcid++;
+
+ if (xport_ctx->free_lcid >= xport_ctx->max_lcid)
+ {
+ xport_ctx->free_lcid = 1;
+ }
+
+ open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
+ continue;
+ }
+
+ open_ch_ctx = smem_list_next(open_ch_ctx);
+ }
+
+ ch_ctx->lcid = xport_ctx->free_lcid;
+
+ /* Append the channel to the transport interface's open_list */
smem_list_append(&if_ptr->glink_core_priv->open_list, ch_ctx);
/* release lock before context switch otherwise it is causing deadlock */
@@ -454,6 +491,7 @@
{
glink_channel_ctx_type *open_ch_ctx, *dummy_open_ch_ctx;
glink_core_xport_ctx_type *xport_ctx;
+ glink_remote_state_type remote_state;
ASSERT(if_ptr != NULL);
@@ -489,9 +527,16 @@
case GLINK_LOCAL_CH_CLOSED:
/* Channel fully closed - local, remote */
+ glink_os_cs_acquire(&open_ch_ctx->ch_state_cs);
xport_ctx->channel_cleanup(open_ch_ctx);
smem_list_delete(&if_ptr->glink_core_priv->open_list, open_ch_ctx);
+ remote_state = open_ch_ctx->remote_state;
+ glink_os_cs_release(&open_ch_ctx->ch_state_cs);
+
+ if (remote_state != GLINK_REMOTE_CH_CLEANUP)
+ {
glink_os_free(open_ch_ctx);
+ }
break;
default:
@@ -621,7 +666,6 @@
if_ptr->tx_cmd_ch_close == NULL ||
if_ptr->tx_cmd_ch_remote_open_ack == NULL ||
if_ptr->tx_cmd_ch_remote_close_ack == NULL ||
- if_ptr->tx_cmd_set_sigs == NULL ||
if_ptr->ssr == NULL)
{
GLINK_LOG_EVENT(GLINK_EVENT_REGISTER_XPORT, NULL, cfg->name,
@@ -658,6 +702,7 @@
xport_ctx->xport = cfg->name;
xport_ctx->remote_ss = cfg->remote_ss;
xport_ctx->free_lcid = 1; /* lcid 0 is reserved for invalid channel */
+ xport_ctx->max_lcid = cfg->max_cid; /* Max channel ID supported by transport */
xport_ctx->version_array = cfg->version;
xport_ctx->version_indx = cfg->version_count - 1;
diff --git a/platform/msm_shared/glink/glink_core_if.c b/platform/msm_shared/glink/glink_core_if.c
index 4631e66..3a71422 100644
--- a/platform/msm_shared/glink/glink_core_if.c
+++ b/platform/msm_shared/glink/glink_core_if.c
@@ -112,20 +112,19 @@
glinki_scan_notif_list_and_notify(if_ptr, GLINK_LINK_STATE_UP);
}
-
/*===========================================================================
FUNCTION glink_clean_channel_ctx
===========================================================================*/
/**
- This is called when channel is fully closed
- Clean up the context and redeem channel id if possible
+ This is called when channel is fully closed.
+ Clean up the context and redeem channel id if possible.
@param[in] xport_ctx transport context
@param[in] channel_ctx channel context
- @return None
+ @return None.
@sideeffects None.
@dependencies This function needs to be called in safe context
which is critical sections locked - channel_q_cs
@@ -137,7 +136,7 @@
glink_channel_ctx_type *channel_ctx
)
{
- xport_ctx->channel_cleanup( channel_ctx );
+ smem_list_delete(&xport_ctx->open_list, channel_ctx);
if( channel_ctx->lcid == ( xport_ctx->free_lcid - 1 ) )
{
@@ -146,7 +145,7 @@
xport_ctx->free_lcid--;
}
- smem_list_delete(&xport_ctx->open_list, channel_ctx);
+ xport_ctx->channel_cleanup(channel_ctx);
}
/*===========================================================================
@@ -517,7 +516,6 @@
/* Found channel */
glink_os_cs_acquire( &open_ch_ctx->ch_state_cs );
-
GLINK_LOG_EVENT(GLINK_EVENT_CH_CLOSE_ACK, open_ch_ctx->name,
xport_ctx->xport, xport_ctx->remote_ss, lcid);
@@ -590,6 +588,8 @@
{
if( open_ch_ctx->rcid == rcid )
{
+ glink_remote_state_type remote_state;
+
GLINK_LOG_EVENT( GLINK_EVENT_CH_REMOTE_CLOSE, open_ch_ctx->name,
xport_ctx->xport, xport_ctx->remote_ss, rcid);
/* Found channel, transition to appropriate state based on current state
@@ -607,6 +607,8 @@
glink_clean_channel_ctx( xport_ctx, open_ch_ctx );
}
+ remote_state = open_ch_ctx->remote_state;
+
glink_os_cs_release(&open_ch_ctx->ch_state_cs);
glink_os_cs_release(&xport_ctx->channel_q_cs);
@@ -615,8 +617,11 @@
if( open_ch_ctx->local_state == GLINK_LOCAL_CH_CLOSED )
{
+ if (remote_state != GLINK_REMOTE_CH_CLEANUP)
+ {
glink_os_free(open_ch_ctx);
}
+ }
else
{
/* Inform the client */
diff --git a/platform/msm_shared/include/glink_core_if.h b/platform/msm_shared/include/glink_core_if.h
index dbd7853..4da917d 100644
--- a/platform/msm_shared/include/glink_core_if.h
+++ b/platform/msm_shared/include/glink_core_if.h
@@ -51,6 +51,14 @@
/*===========================================================================
MACRO DECLARATIONS
===========================================================================*/
+/* Limit of the proportion of total QoS requests */
+#define GLINK_QOS_RATE_LIMIT_COEFF (0.7)
+
+/* Number of QoS tokens given at refill */
+#define GLINK_QOS_TOKENS (10)
+
+/* Number of QoS buckets */
+#define GLINK_QOS_BUCKETS (1)
/*===========================================================================
TYPE DECLARATIONS
@@ -88,6 +96,7 @@
os_event_type event; /* Event to signal Tx thread */
os_cs_type tx_q_cs; /* Lock to protect Tx queue */
smem_list_type tx_q; /* Tx channel queue */
+ uint32 qos_rate_sum; /* Sum of rates of registered QoS requests */
} glink_tx_xport_ctx_type;
/** G-Link Local channel states */
@@ -117,7 +126,12 @@
GLINK_REMOTE_CH_OPENED,
/* Glink channel state when SSR is received from remote sub-system */
- GLINK_REMOTE_CH_SSR_RESET
+ GLINK_REMOTE_CH_SSR_RESET,
+
+ /** G-Link channel is pending cleanup.
+ This state is used for deferred channel cleanup in case
+ it sits in Tx scheduler queue */
+ GLINK_REMOTE_CH_CLEANUP,
}glink_remote_state_type;
@@ -311,6 +325,9 @@
/* Transport's capabilities */
uint32 xport_capabilities;
+ /* Max lcid */
+ uint32 max_lcid;
+
/* Free lcid */
uint32 free_lcid;
diff --git a/platform/msm_shared/include/glink_internal.h b/platform/msm_shared/include/glink_internal.h
index 5d8cc21..d78fe34 100644
--- a/platform/msm_shared/include/glink_internal.h
+++ b/platform/msm_shared/include/glink_internal.h
@@ -95,7 +95,11 @@
GLINK_EVENT_CH_MIGRATION_IN_PROGRESS,
GLINK_EVENT_XPORT_INTERNAL,
GLINK_EVENT_TRACER_PKT_FAILURE,
- GLINK_EVENT_TXV_INVALID_BUFFER
+ GLINK_EVENT_TXV_INVALID_BUFFER,
+ GLINK_EVENT_CH_QOS_REG,
+ GLINK_EVENT_CH_QOS_CANCEL,
+ GLINK_EVENT_CH_QOS_START,
+ GLINK_EVENT_CH_QOS_STOP,
}glink_log_event_type;
typedef struct _glink_channel_intents_type {
@@ -103,6 +107,9 @@
/* Link for a channel in Tx queue */
struct _glink_channel_intents_type* next;
+ /* Pointer to channel context */
+ glink_channel_ctx_type *ch_ctx;
+
/* Critical section to protest access to intent queues */
os_cs_type intent_q_cs;
@@ -137,6 +144,32 @@
} glink_channel_intents_type;
+
+typedef struct _glink_channel_qos_type {
+ /* qos request count */
+ uint32 qos_req_count;
+
+ /* qos request packet size */
+ size_t qos_pkt_size;
+
+ /* qos request latency */
+ uint32 qos_latency_us;
+
+ /* qos request rate */
+ uint32 qos_rate;
+
+ /* qos priority */
+ uint32 qos_tokens;
+
+ /* qos transport context */
+ void *qos_transport_ctx;
+
+ /* qos start time for priority balancing */
+ os_timetick_type qos_start_priority_time;
+
+} glink_channel_qos_type;
+
+
struct glink_channel_ctx {
/* Link needed for use with list APIs. Must be at the head of the struct */
smem_list_link_type link;
@@ -171,6 +204,15 @@
/* channel intent collection */
glink_channel_intents_type *pintents;
+ /* Critical section to protest access to QoS context */
+ os_cs_type qos_cs;
+
+ /* qos priority */
+ uint32 qos_priority;
+
+ /* channel QoS context */
+ glink_channel_qos_type *qosctx;
+
/* Interface pointer with with this channel is registered */
glink_transport_if_type *if_ptr;
@@ -577,4 +619,37 @@
/*=========================================================================*/
void glink_core_setup_intentless_xport(glink_transport_if_type *if_ptr);
+/*===========================================================================
+ FUNCTION glink_core_qos_get_priority
+===========================================================================*/
+/**
+
+ Calculates pinitial priority for QoS request.
+
+ @param[in] if_ptr The Pointer to the interface instance.
+ @param[in] req_rate The requested rate.
+
+ @return Priority.
+
+ @sideeffects None.
+*/
+/*=========================================================================*/
+uint32 glink_core_qos_get_priority(glink_transport_if_type *if_ptr, uint32 req_rate);
+
+/*===========================================================================
+ FUNCTION glink_core_qos_cancel
+===========================================================================*/
+/**
+
+ Releases QoS resources.
+
+ @param[in] open_ch_ctx Pointer to the channel context.
+
+ @return None.
+
+ @sideeffects None.
+*/
+/*=========================================================================*/
+void glink_core_qos_cancel(glink_channel_ctx_type *open_ch_ctx);
+
#endif /* GLINK_INTERNAL_H */
diff --git a/platform/msm_shared/include/glink_os_type.h b/platform/msm_shared/include/glink_os_type.h
index a129372..634a2ef 100644
--- a/platform/msm_shared/include/glink_os_type.h
+++ b/platform/msm_shared/include/glink_os_type.h
@@ -49,7 +49,11 @@
===========================================================================*/
#define OS_LOG_INIT( ) glink_os_log_init()
+#define GLINK_OS_SEC_TO_USEC (1000000ULL)
+#define GLINK_OS_SEC_TO_TICK (19200000ULL)
+#define GLINK_OS_TICK_TO_USEC(t) ((t)*10ULL/192ULL)
+#define GLINK_OS_USEC_TO_TICK(u) ((u)*192ULL/10ULL)
/*===========================================================================
TYPE DEFINITIONS
===========================================================================*/
@@ -88,4 +92,6 @@
uint32_t irq_out;
} os_ipc_intr_type;
+typedef unsigned long long os_timetick_type;
+
#endif /* OS_TYPE_H */
diff --git a/platform/msm_shared/include/glink_transport_if.h b/platform/msm_shared/include/glink_transport_if.h
index 14f0982..c0855e7 100644
--- a/platform/msm_shared/include/glink_transport_if.h
+++ b/platform/msm_shared/include/glink_transport_if.h
@@ -83,7 +83,8 @@
GLINK_XPORT_RPM = 100,
GLINK_XPORT_SMD = 200,
GLINK_XPORT_CP_ENGINE = 300,
- GLINK_MIN_PRIORITY = GLINK_XPORT_CP_ENGINE,
+ GLINK_XPORT_UART = 400,
+ GLINK_MIN_PRIORITY = GLINK_XPORT_UART,
GLINK_INVALID_PRIORITY
} glink_xport_priority;
@@ -93,7 +94,6 @@
void *data; /* Pointer to the data buffer to be transmitted */
const void *pkt_priv; /* Per packet private data */
- uint32 cid; /* Local channel ID being used to transmit data */
uint32 iid; /* Remote intent ID being used to transmit data */
size_t size; /* Size of data buffer */
size_t size_remaining; /* Size left to transmit */
@@ -264,6 +264,76 @@
glink_transport_if_type *if_ptr /* Pointer to the interface instance */
);
+/** Provides data rate (tokens/sec) achievable by the transport for given
+ packet size and latency. */
+typedef uint32 (*get_req_rate_fn)
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 latency_us, /* latency in us */
+ size_t pkt_size /* Size of the packet */
+);
+
+/** Allocates context structure to use by transport servicing given QoS request. */
+typedef void* (*alloc_req_ctx_fn)
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ uint32 latency_us, /* latency in us */
+ size_t pkt_size /* Size of the packet */
+);
+
+/** Frees context structure used by transport servicing given QoS request. */
+typedef void (*free_req_ctx_fn)
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ void *qos_ctx /* Pointer to the transport QoS context */
+);
+
+/** Starts QoS mode. */
+typedef void (*start_req_fn)
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ void *qos_ctx /* Pointer to the transport QoS context */
+);
+
+/** Stops QoS mode. */
+typedef void (*stop_req_fn)
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ void *qos_ctx /* Pointer to the transport QoS context */
+);
+
+/** Provides ramp up time in microseconds. */
+typedef uint32 (*get_ramp_time_fn)
+(
+ glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
+ void *qos_ctx /* Pointer to the transport QoS context */
+);
+
+
+/**
+* Data Structure for GLink Core to call into transport QoS API
+*
+* This structure is used by the GLink core to operate transport
+* This set of function pointers to to be filled in by the transport
+* abstraction layer.
+*/
+typedef struct glink_transport_qos_if_s {
+ /** Provides maximum data rate (tokens/sec) associated with transport. */
+ uint32 max_rate;
+ /** Provides data rate achievable by the transport for given request. */
+ get_req_rate_fn get_req_rate;
+ /** Allocates context structure to use by transport servicing given QoS request. */
+ alloc_req_ctx_fn alloc_req_ctx;
+ /** Frees context structure used by transport servicing given QoS request. */
+ free_req_ctx_fn free_req_ctx;
+ /** Starts QoS mode. */
+ start_req_fn start_req;
+ /** Stops QoS mode. */
+ stop_req_fn stop_req;
+ /** Provides ramp up time in microseconds. */
+ get_ramp_time_fn get_ramp_time;
+
+} glink_transport_qos_if_type;
/**
* Data Structure for GLink Core to call into transport API
@@ -359,6 +429,9 @@
/* glink transport priority */
glink_xport_priority glink_priority;
+
+ /* pointer to glink transport QoS interface */
+ glink_transport_qos_if_type *qos_functbl;
};
#endif //GLINK_TRANSPORT_IF_H