usb: gadget: Add support for rndis flow control callback
Allow registration for data flow control call back from rndis functions supporting different transport i.e. BAM2BAM_IPA, GSI_IPA. Change-Id: I09df5f7f81e9d9ed0cfd5e54d481db87727bbc75 Signed-off-by: Hemant Kumar <hemantk@codeaurora.org>
This commit is contained in:
parent
c34d39a511
commit
a86fe70b61
3 changed files with 61 additions and 7 deletions
|
@ -1018,7 +1018,7 @@ static struct usb_function *rndis_alloc(struct usb_function_instance *fi)
|
||||||
rndis->port.func.disable = rndis_disable;
|
rndis->port.func.disable = rndis_disable;
|
||||||
rndis->port.func.free_func = rndis_free;
|
rndis->port.func.free_func = rndis_free;
|
||||||
|
|
||||||
params = rndis_register(rndis_response_available, rndis);
|
params = rndis_register(rndis_response_available, rndis, NULL);
|
||||||
if (IS_ERR(params)) {
|
if (IS_ERR(params)) {
|
||||||
kfree(rndis);
|
kfree(rndis);
|
||||||
return ERR_CAST(params);
|
return ERR_CAST(params);
|
||||||
|
|
|
@ -831,10 +831,16 @@ int rndis_msg_parser(struct rndis_params *params, u8 *buf)
|
||||||
case RNDIS_MSG_HALT:
|
case RNDIS_MSG_HALT:
|
||||||
pr_debug("%s: RNDIS_MSG_HALT\n",
|
pr_debug("%s: RNDIS_MSG_HALT\n",
|
||||||
__func__);
|
__func__);
|
||||||
params->state = RNDIS_UNINITIALIZED;
|
if (params->state == RNDIS_DATA_INITIALIZED) {
|
||||||
if (params->dev) {
|
if (params->flow_ctrl_enable) {
|
||||||
netif_carrier_off(params->dev);
|
params->flow_ctrl_enable(true, params);
|
||||||
netif_stop_queue(params->dev);
|
} else {
|
||||||
|
if (params->dev) {
|
||||||
|
netif_carrier_off(params->dev);
|
||||||
|
netif_stop_queue(params->dev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
params->state = RNDIS_UNINITIALIZED;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -886,7 +892,8 @@ static inline void rndis_put_nr(int nr)
|
||||||
ida_simple_remove(&rndis_ida, nr);
|
ida_simple_remove(&rndis_ida, nr);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct rndis_params *rndis_register(void (*resp_avail)(void *v), void *v)
|
struct rndis_params *rndis_register(void (*resp_avail)(void *v), void *v,
|
||||||
|
void (*flow_ctrl_enable)(bool enable, struct rndis_params *params))
|
||||||
{
|
{
|
||||||
struct rndis_params *params;
|
struct rndis_params *params;
|
||||||
int i;
|
int i;
|
||||||
|
@ -930,6 +937,7 @@ struct rndis_params *rndis_register(void (*resp_avail)(void *v), void *v)
|
||||||
params->state = RNDIS_UNINITIALIZED;
|
params->state = RNDIS_UNINITIALIZED;
|
||||||
params->media_state = RNDIS_MEDIA_STATE_DISCONNECTED;
|
params->media_state = RNDIS_MEDIA_STATE_DISCONNECTED;
|
||||||
params->resp_avail = resp_avail;
|
params->resp_avail = resp_avail;
|
||||||
|
params->flow_ctrl_enable = flow_ctrl_enable;
|
||||||
params->v = v;
|
params->v = v;
|
||||||
INIT_LIST_HEAD(&(params->resp_queue));
|
INIT_LIST_HEAD(&(params->resp_queue));
|
||||||
pr_debug("%s: configNr = %d\n", __func__, i);
|
pr_debug("%s: configNr = %d\n", __func__, i);
|
||||||
|
@ -1015,6 +1023,47 @@ void rndis_set_max_pkt_xfer(struct rndis_params *params, u8 max_pkt_per_xfer)
|
||||||
params->max_pkt_per_xfer = max_pkt_per_xfer;
|
params->max_pkt_per_xfer = max_pkt_per_xfer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rndis_flow_control: enable/disable flow control with USB RNDIS interface
|
||||||
|
* params - RNDIS network parameter
|
||||||
|
* enable_flow_control - true: perform flow control, false: disable flow control
|
||||||
|
*
|
||||||
|
* In hw accelerated mode, this function triggers functionality to start/stop
|
||||||
|
* endless transfers, otherwise it enables/disables RNDIS network interface.
|
||||||
|
*/
|
||||||
|
void rndis_flow_control(struct rndis_params *params, bool enable_flow_control)
|
||||||
|
{
|
||||||
|
if (!params) {
|
||||||
|
pr_err("%s: failed, params NULL\n", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pr_debug("%s(): params->state:%x\n", __func__, params->state);
|
||||||
|
|
||||||
|
if (enable_flow_control) {
|
||||||
|
if (params->state == RNDIS_DATA_INITIALIZED) {
|
||||||
|
if (params->flow_ctrl_enable) {
|
||||||
|
params->flow_ctrl_enable(enable_flow_control, params);
|
||||||
|
} else {
|
||||||
|
netif_carrier_off(params->dev);
|
||||||
|
netif_stop_queue(params->dev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
params->state = RNDIS_INITIALIZED;
|
||||||
|
} else {
|
||||||
|
if (params->state != RNDIS_DATA_INITIALIZED) {
|
||||||
|
if (params->flow_ctrl_enable) {
|
||||||
|
params->flow_ctrl_enable(enable_flow_control, params);
|
||||||
|
} else {
|
||||||
|
netif_carrier_on(params->dev);
|
||||||
|
if (netif_running(params->dev))
|
||||||
|
netif_wake_queue(params->dev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
params->state = RNDIS_DATA_INITIALIZED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void rndis_add_hdr(struct sk_buff *skb)
|
void rndis_add_hdr(struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct rndis_packet_msg_type *header;
|
struct rndis_packet_msg_type *header;
|
||||||
|
|
|
@ -193,13 +193,17 @@ typedef struct rndis_params
|
||||||
u8 max_pkt_per_xfer;
|
u8 max_pkt_per_xfer;
|
||||||
const char *vendorDescr;
|
const char *vendorDescr;
|
||||||
void (*resp_avail)(void *v);
|
void (*resp_avail)(void *v);
|
||||||
|
void (*flow_ctrl_enable)(bool enable,
|
||||||
|
struct rndis_params *params);
|
||||||
|
|
||||||
void *v;
|
void *v;
|
||||||
struct list_head resp_queue;
|
struct list_head resp_queue;
|
||||||
} rndis_params;
|
} rndis_params;
|
||||||
|
|
||||||
/* RNDIS Message parser and other useless functions */
|
/* RNDIS Message parser and other useless functions */
|
||||||
int rndis_msg_parser(struct rndis_params *params, u8 *buf);
|
int rndis_msg_parser(struct rndis_params *params, u8 *buf);
|
||||||
struct rndis_params *rndis_register(void (*resp_avail)(void *v), void *v);
|
struct rndis_params *rndis_register(void (*resp_avail)(void *v), void *v,
|
||||||
|
void (*flow_ctrl_enable)(bool enable, struct rndis_params *params));
|
||||||
void rndis_deregister(struct rndis_params *params);
|
void rndis_deregister(struct rndis_params *params);
|
||||||
int rndis_set_param_dev(struct rndis_params *params, struct net_device *dev,
|
int rndis_set_param_dev(struct rndis_params *params, struct net_device *dev,
|
||||||
u16 *cdc_filter);
|
u16 *cdc_filter);
|
||||||
|
@ -219,5 +223,6 @@ int rndis_signal_connect(struct rndis_params *params);
|
||||||
int rndis_signal_disconnect(struct rndis_params *params);
|
int rndis_signal_disconnect(struct rndis_params *params);
|
||||||
int rndis_state(struct rndis_params *params);
|
int rndis_state(struct rndis_params *params);
|
||||||
extern void rndis_set_host_mac(struct rndis_params *params, const u8 *addr);
|
extern void rndis_set_host_mac(struct rndis_params *params, const u8 *addr);
|
||||||
|
void rndis_flow_control(struct rndis_params *params, bool enable_flow_control);
|
||||||
|
|
||||||
#endif /* _LINUX_RNDIS_H */
|
#endif /* _LINUX_RNDIS_H */
|
||||||
|
|
Loading…
Add table
Reference in a new issue