Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a9a9aafa authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "usb: gadget: Add support for rndis flow control callback"

parents 8d22e8f6 ee4a0d21
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1029,7 +1029,7 @@ static struct usb_function *rndis_alloc(struct usb_function_instance *fi)
	rndis->port.func.disable = rndis_disable;
	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)) {
		kfree(rndis);
		return ERR_CAST(params);
+56 −5
Original line number Diff line number Diff line
@@ -814,11 +814,17 @@ int rndis_msg_parser(struct rndis_params *params, u8 *buf)
	case RNDIS_MSG_HALT:
		pr_debug("%s: RNDIS_MSG_HALT\n",
			__func__);
		params->state = RNDIS_UNINITIALIZED;
		if (params->state == RNDIS_DATA_INITIALIZED) {
			if (params->flow_ctrl_enable) {
				params->flow_ctrl_enable(true, params);
			} else {
				if (params->dev) {
					netif_carrier_off(params->dev);
					netif_stop_queue(params->dev);
				}
			}
			params->state = RNDIS_UNINITIALIZED;
		}
		return 0;

	case RNDIS_MSG_QUERY:
@@ -872,7 +878,8 @@ static inline void rndis_put_nr(int 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;
	int i;
@@ -916,6 +923,7 @@ struct rndis_params *rndis_register(void (*resp_avail)(void *v), void *v)
	params->state = RNDIS_UNINITIALIZED;
	params->media_state = RNDIS_MEDIA_STATE_DISCONNECTED;
	params->resp_avail = resp_avail;
	params->flow_ctrl_enable = flow_ctrl_enable;
	params->v = v;
	INIT_LIST_HEAD(&params->resp_queue);
	pr_debug("%s: configNr = %d\n", __func__, i);
@@ -999,6 +1007,49 @@ void rndis_set_max_pkt_xfer(struct rndis_params *params, u8 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)
{
	struct rndis_packet_msg_type *header;
+6 −1
Original line number Diff line number Diff line
@@ -173,13 +173,17 @@ typedef struct rndis_params {
	u8			max_pkt_per_xfer;
	const char		*vendorDescr;
	void			(*resp_avail)(void *v);
	void			(*flow_ctrl_enable)(bool enable,
			struct rndis_params *params);

	void			*v;
	struct list_head	resp_queue;
} rndis_params;

/* RNDIS Message parser and other useless functions */
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);
int  rndis_set_param_dev(struct rndis_params *params, struct net_device *dev,
			 u16 *cdc_filter);
@@ -199,5 +203,6 @@ int rndis_signal_connect(struct rndis_params *params);
int  rndis_signal_disconnect(struct rndis_params *params);
int  rndis_state(struct rndis_params *params);
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 */