Loading core/dfc.h +22 −0 Original line number Diff line number Diff line Loading @@ -292,6 +292,28 @@ TRACE_EVENT(dfc_adjust_grant, __entry->rx_bytes, __entry->inflight, __entry->a_grant) ); TRACE_EVENT(dfc_watchdog, TP_PROTO(u8 mux_id, u8 bearer_id, u8 event), TP_ARGS(mux_id, bearer_id, event), TP_STRUCT__entry( __field(u8, mux_id) __field(u8, bearer_id) __field(u8, event) ), TP_fast_assign( __entry->mux_id = mux_id; __entry->bearer_id = bearer_id; __entry->event = event; ), TP_printk("mid=%u bid=%u event=%u", __entry->mux_id, __entry->bearer_id, __entry->event) ); #endif /* _TRACE_DFC_H */ /* This part must be outside protection */ Loading core/dfc_qmap.c +14 −7 Original line number Diff line number Diff line Loading @@ -127,10 +127,11 @@ static struct dfc_tx_link_status_ind_msg_v01 qmap_tx_ind; static struct dfc_qmi_data __rcu *qmap_dfc_data; static atomic_t qmap_txid; static void *rmnet_ctl_handle; static bool dfc_config_acked; extern struct rmnet_ctl_client_if rmnet_ctl_if; static struct rmnet_ctl_client_if *rmnet_ctl; static void dfc_qmap_send_config(struct dfc_qmi_data *data); static void dfc_qmap_send_end_marker_cnf(struct qos_info *qos, u8 bearer_id, u16 seq, u32 tx_id); Loading Loading @@ -320,6 +321,9 @@ static void dfc_qmap_cmd_handler(struct sk_buff *skb) if (cmd->cmd_type != QMAP_CMD_ACK) goto free_skb; } else if (cmd->cmd_type != QMAP_CMD_REQUEST) { if (cmd->cmd_type == QMAP_CMD_ACK && cmd->cmd_name == QMAP_DFC_CONFIG) dfc_config_acked = true; goto free_skb; } Loading @@ -331,6 +335,12 @@ static void dfc_qmap_cmd_handler(struct sk_buff *skb) goto free_skb; } /* Re-send DFC config once if needed */ if (unlikely(!dfc_config_acked)) { dfc_qmap_send_config(dfc); dfc_config_acked = true; } switch (cmd->cmd_name) { case QMAP_DFC_IND: rc = dfc_qmap_handle_ind(dfc, skb); Loading Loading @@ -504,7 +514,7 @@ int dfc_qmap_client_init(void *port, int index, struct svc_info *psvc, atomic_set(&qmap_txid, 0); rmnet_ctl = symbol_get(rmnet_ctl_if); rmnet_ctl = rmnet_ctl_if(); if (!rmnet_ctl) { pr_err("rmnet_ctl module not loaded\n"); goto out; Loading @@ -521,6 +531,7 @@ int dfc_qmap_client_init(void *port, int index, struct svc_info *psvc, pr_info("DFC QMAP init\n"); dfc_config_acked = false; dfc_qmap_send_config(data); out: Loading @@ -547,11 +558,7 @@ void dfc_qmap_client_exit(void *dfc_data) synchronize_rcu(); kfree(data); if (rmnet_ctl) { symbol_put(rmnet_ctl_if); rmnet_ctl = NULL; } pr_info("DFC QMAP exit\n"); } core/dfc_qmi.c +8 −3 Original line number Diff line number Diff line Loading @@ -1034,14 +1034,18 @@ static int dfc_update_fc_map(struct net_device *dev, struct qos_info *qos, itm->grant_size = adjusted_grant; /* No further query if the adjusted grant is less * than 20% of the original grant * than 20% of the original grant. Add to watch to * recover if no indication is received. */ if (dfc_qmap && is_query && itm->grant_size < (fc_info->num_bytes / 5)) itm->grant_size < (fc_info->num_bytes / 5)) { itm->grant_thresh = itm->grant_size; else qmi_rmnet_watchdog_add(itm); } else { itm->grant_thresh = qmi_rmnet_grant_per(itm->grant_size); qmi_rmnet_watchdog_remove(itm); } itm->seq = fc_info->seq_num; itm->ack_req = ack_req; Loading Loading @@ -1143,6 +1147,7 @@ static void dfc_update_tx_link_status(struct net_device *dev, itm->grant_size = 0; itm->tcp_bidir = false; itm->bytes_in_flight = 0; qmi_rmnet_watchdog_remove(itm); dfc_bearer_flow_ctl(dev, itm, qos); } else if (itm->grant_size == 0 && tx_status && !itm->rat_switch) { itm->grant_size = DEFAULT_GRANT; Loading core/qmi_rmnet.c +126 −9 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <linux/rtnetlink.h> #include <uapi/linux/rtnetlink.h> #include <net/pkt_sched.h> #include <net/tcp.h> #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/ip.h> Loading Loading @@ -53,6 +54,7 @@ unsigned int rmnet_wq_frequency __read_mostly = 1000; 1 : rmnet_wq_frequency/10) * (HZ/100)) #define NO_DELAY (0x0000 * HZ) #define PS_INTERVAL_KT (ms_to_ktime(1000)) #define WATCHDOG_EXPIRE_JF (msecs_to_jiffies(50)) #ifdef CONFIG_QTI_QMI_DFC static unsigned int qmi_rmnet_scale_factor = 5; Loading Loading @@ -233,6 +235,89 @@ static void qmi_rmnet_reset_txq(struct net_device *dev, unsigned int txq) } } /** * qmi_rmnet_watchdog_fn - watchdog timer func */ static void qmi_rmnet_watchdog_fn(struct timer_list *t) { struct rmnet_bearer_map *bearer; bearer = container_of(t, struct rmnet_bearer_map, watchdog); trace_dfc_watchdog(bearer->qos->mux_id, bearer->bearer_id, 2); spin_lock_bh(&bearer->qos->qos_lock); if (bearer->watchdog_quit) goto done; /* * Possible stall, try to recover. Enable 80% query and jumpstart * the bearer if disabled. */ bearer->watchdog_expire_cnt++; bearer->bytes_in_flight = 0; if (!bearer->grant_size) { bearer->grant_size = DEFAULT_CALL_GRANT; bearer->grant_thresh = qmi_rmnet_grant_per(bearer->grant_size); dfc_bearer_flow_ctl(bearer->qos->vnd_dev, bearer, bearer->qos); } else { bearer->grant_thresh = qmi_rmnet_grant_per(bearer->grant_size); } done: bearer->watchdog_started = false; spin_unlock_bh(&bearer->qos->qos_lock); } /** * qmi_rmnet_watchdog_add - add the bearer to watch * Needs to be called with qos_lock */ void qmi_rmnet_watchdog_add(struct rmnet_bearer_map *bearer) { bearer->watchdog_quit = false; if (bearer->watchdog_started) return; bearer->watchdog_started = true; mod_timer(&bearer->watchdog, jiffies + WATCHDOG_EXPIRE_JF); trace_dfc_watchdog(bearer->qos->mux_id, bearer->bearer_id, 1); } /** * qmi_rmnet_watchdog_remove - remove the bearer from watch * Needs to be called with qos_lock */ void qmi_rmnet_watchdog_remove(struct rmnet_bearer_map *bearer) { bearer->watchdog_quit = true; if (!bearer->watchdog_started) return; del_timer(&bearer->watchdog); bearer->watchdog_started = false; trace_dfc_watchdog(bearer->qos->mux_id, bearer->bearer_id, 0); } /** * qmi_rmnet_bearer_clean - clean the removed bearer * Needs to be called with rtn_lock but not qos_lock */ static void qmi_rmnet_bearer_clean(struct qos_info *qos) { if (qos->removed_bearer) { qos->removed_bearer->watchdog_quit = true; del_timer_sync(&qos->removed_bearer->watchdog); kfree(qos->removed_bearer); qos->removed_bearer = NULL; } } static struct rmnet_bearer_map *__qmi_rmnet_bearer_get( struct qos_info *qos_info, u8 bearer_id) { Loading @@ -252,6 +337,8 @@ static struct rmnet_bearer_map *__qmi_rmnet_bearer_get( bearer->grant_thresh = qmi_rmnet_grant_per(bearer->grant_size); bearer->mq_idx = INVALID_MQ; bearer->ack_mq_idx = INVALID_MQ; bearer->qos = qos_info; timer_setup(&bearer->watchdog, qmi_rmnet_watchdog_fn, 0); list_add(&bearer->list, &qos_info->bearer_head); } Loading Loading @@ -287,7 +374,7 @@ static void __qmi_rmnet_bearer_put(struct net_device *dev, /* Remove from bearer map */ list_del(&bearer->list); kfree(bearer); qos_info->removed_bearer = bearer; } } Loading Loading @@ -415,6 +502,9 @@ static int qmi_rmnet_add_flow(struct net_device *dev, struct tcmsg *tcm, done: spin_unlock_bh(&qos_info->qos_lock); qmi_rmnet_bearer_clean(qos_info); return rc; } Loading Loading @@ -458,6 +548,9 @@ qmi_rmnet_del_flow(struct net_device *dev, struct tcmsg *tcm, netif_tx_wake_all_queues(dev); spin_unlock_bh(&qos_info->qos_lock); qmi_rmnet_bearer_clean(qos_info); return 0; } Loading Loading @@ -726,6 +819,8 @@ void qmi_rmnet_enable_all_flows(struct net_device *dev) bearer->tcp_bidir = false; bearer->rat_switch = false; qmi_rmnet_watchdog_remove(bearer); if (bearer->tx_off) continue; Loading Loading @@ -779,16 +874,14 @@ void qmi_rmnet_burst_fc_check(struct net_device *dev, } EXPORT_SYMBOL(qmi_rmnet_burst_fc_check); static bool qmi_rmnet_is_tcp_ack(struct sk_buff *skb) static bool _qmi_rmnet_is_tcp_ack(struct sk_buff *skb) { unsigned int len = skb->len; switch (skb->protocol) { /* TCPv4 ACKs */ case htons(ETH_P_IP): if ((ip_hdr(skb)->protocol == IPPROTO_TCP) && (ip_hdr(skb)->ihl == 5) && (len == 40 || len == 52) && (ntohs(ip_hdr(skb)->tot_len) - (ip_hdr(skb)->ihl << 2) == tcp_hdr(skb)->doff << 2) && ((tcp_flag_word(tcp_hdr(skb)) & cpu_to_be32(0x00FF0000)) == TCP_FLAG_ACK)) return true; Loading @@ -797,7 +890,8 @@ static bool qmi_rmnet_is_tcp_ack(struct sk_buff *skb) /* TCPv6 ACKs */ case htons(ETH_P_IPV6): if ((ipv6_hdr(skb)->nexthdr == IPPROTO_TCP) && (len == 60 || len == 72) && (ntohs(ipv6_hdr(skb)->payload_len) == (tcp_hdr(skb)->doff) << 2) && ((tcp_flag_word(tcp_hdr(skb)) & cpu_to_be32(0x00FF0000)) == TCP_FLAG_ACK)) return true; Loading @@ -807,6 +901,19 @@ static bool qmi_rmnet_is_tcp_ack(struct sk_buff *skb) return false; } static inline bool qmi_rmnet_is_tcp_ack(struct sk_buff *skb) { /* Locally generated TCP acks */ if (skb_is_tcp_pure_ack(skb)) return true; /* Forwarded */ if (unlikely(_qmi_rmnet_is_tcp_ack(skb))) return true; return false; } static int qmi_rmnet_get_queue_sa(struct qos_info *qos, struct sk_buff *skb) { struct rmnet_flow_map *itm; Loading Loading @@ -873,7 +980,8 @@ inline unsigned int qmi_rmnet_grant_per(unsigned int grant) } EXPORT_SYMBOL(qmi_rmnet_grant_per); void *qmi_rmnet_qos_init(struct net_device *real_dev, u8 mux_id) void *qmi_rmnet_qos_init(struct net_device *real_dev, struct net_device *vnd_dev, u8 mux_id) { struct qos_info *qos; Loading @@ -883,6 +991,7 @@ void *qmi_rmnet_qos_init(struct net_device *real_dev, u8 mux_id) qos->mux_id = mux_id; qos->real_dev = real_dev; qos->vnd_dev = vnd_dev; qos->tran_num = 0; INIT_LIST_HEAD(&qos->flow_head); INIT_LIST_HEAD(&qos->bearer_head); Loading @@ -894,10 +1003,18 @@ EXPORT_SYMBOL(qmi_rmnet_qos_init); void qmi_rmnet_qos_exit_pre(void *qos) { struct qos_info *qosi = (struct qos_info *)qos; struct rmnet_bearer_map *bearer; if (!qos) return; list_add(&((struct qos_info *)qos)->list, &qos_cleanup_list); list_for_each_entry(bearer, &qosi->bearer_head, list) { bearer->watchdog_quit = true; del_timer_sync(&bearer->watchdog); } list_add(&qosi->list, &qos_cleanup_list); } EXPORT_SYMBOL(qmi_rmnet_qos_exit_pre); Loading core/qmi_rmnet.h +4 −2 Original line number Diff line number Diff line Loading @@ -55,7 +55,8 @@ qmi_rmnet_all_flows_enabled(struct net_device *dev) #endif #ifdef CONFIG_QTI_QMI_DFC void *qmi_rmnet_qos_init(struct net_device *real_dev, u8 mux_id); void *qmi_rmnet_qos_init(struct net_device *real_dev, struct net_device *vnd_dev, u8 mux_id); void qmi_rmnet_qos_exit_pre(void *qos); void qmi_rmnet_qos_exit_post(void); void qmi_rmnet_burst_fc_check(struct net_device *dev, Loading @@ -63,7 +64,8 @@ void qmi_rmnet_burst_fc_check(struct net_device *dev, int qmi_rmnet_get_queue(struct net_device *dev, struct sk_buff *skb); #else static inline void * qmi_rmnet_qos_init(struct net_device *real_dev, u8 mux_id) qmi_rmnet_qos_init(struct net_device *real_dev, struct net_device *vnd_dev, u8 mux_id) { return NULL; } Loading Loading
core/dfc.h +22 −0 Original line number Diff line number Diff line Loading @@ -292,6 +292,28 @@ TRACE_EVENT(dfc_adjust_grant, __entry->rx_bytes, __entry->inflight, __entry->a_grant) ); TRACE_EVENT(dfc_watchdog, TP_PROTO(u8 mux_id, u8 bearer_id, u8 event), TP_ARGS(mux_id, bearer_id, event), TP_STRUCT__entry( __field(u8, mux_id) __field(u8, bearer_id) __field(u8, event) ), TP_fast_assign( __entry->mux_id = mux_id; __entry->bearer_id = bearer_id; __entry->event = event; ), TP_printk("mid=%u bid=%u event=%u", __entry->mux_id, __entry->bearer_id, __entry->event) ); #endif /* _TRACE_DFC_H */ /* This part must be outside protection */ Loading
core/dfc_qmap.c +14 −7 Original line number Diff line number Diff line Loading @@ -127,10 +127,11 @@ static struct dfc_tx_link_status_ind_msg_v01 qmap_tx_ind; static struct dfc_qmi_data __rcu *qmap_dfc_data; static atomic_t qmap_txid; static void *rmnet_ctl_handle; static bool dfc_config_acked; extern struct rmnet_ctl_client_if rmnet_ctl_if; static struct rmnet_ctl_client_if *rmnet_ctl; static void dfc_qmap_send_config(struct dfc_qmi_data *data); static void dfc_qmap_send_end_marker_cnf(struct qos_info *qos, u8 bearer_id, u16 seq, u32 tx_id); Loading Loading @@ -320,6 +321,9 @@ static void dfc_qmap_cmd_handler(struct sk_buff *skb) if (cmd->cmd_type != QMAP_CMD_ACK) goto free_skb; } else if (cmd->cmd_type != QMAP_CMD_REQUEST) { if (cmd->cmd_type == QMAP_CMD_ACK && cmd->cmd_name == QMAP_DFC_CONFIG) dfc_config_acked = true; goto free_skb; } Loading @@ -331,6 +335,12 @@ static void dfc_qmap_cmd_handler(struct sk_buff *skb) goto free_skb; } /* Re-send DFC config once if needed */ if (unlikely(!dfc_config_acked)) { dfc_qmap_send_config(dfc); dfc_config_acked = true; } switch (cmd->cmd_name) { case QMAP_DFC_IND: rc = dfc_qmap_handle_ind(dfc, skb); Loading Loading @@ -504,7 +514,7 @@ int dfc_qmap_client_init(void *port, int index, struct svc_info *psvc, atomic_set(&qmap_txid, 0); rmnet_ctl = symbol_get(rmnet_ctl_if); rmnet_ctl = rmnet_ctl_if(); if (!rmnet_ctl) { pr_err("rmnet_ctl module not loaded\n"); goto out; Loading @@ -521,6 +531,7 @@ int dfc_qmap_client_init(void *port, int index, struct svc_info *psvc, pr_info("DFC QMAP init\n"); dfc_config_acked = false; dfc_qmap_send_config(data); out: Loading @@ -547,11 +558,7 @@ void dfc_qmap_client_exit(void *dfc_data) synchronize_rcu(); kfree(data); if (rmnet_ctl) { symbol_put(rmnet_ctl_if); rmnet_ctl = NULL; } pr_info("DFC QMAP exit\n"); }
core/dfc_qmi.c +8 −3 Original line number Diff line number Diff line Loading @@ -1034,14 +1034,18 @@ static int dfc_update_fc_map(struct net_device *dev, struct qos_info *qos, itm->grant_size = adjusted_grant; /* No further query if the adjusted grant is less * than 20% of the original grant * than 20% of the original grant. Add to watch to * recover if no indication is received. */ if (dfc_qmap && is_query && itm->grant_size < (fc_info->num_bytes / 5)) itm->grant_size < (fc_info->num_bytes / 5)) { itm->grant_thresh = itm->grant_size; else qmi_rmnet_watchdog_add(itm); } else { itm->grant_thresh = qmi_rmnet_grant_per(itm->grant_size); qmi_rmnet_watchdog_remove(itm); } itm->seq = fc_info->seq_num; itm->ack_req = ack_req; Loading Loading @@ -1143,6 +1147,7 @@ static void dfc_update_tx_link_status(struct net_device *dev, itm->grant_size = 0; itm->tcp_bidir = false; itm->bytes_in_flight = 0; qmi_rmnet_watchdog_remove(itm); dfc_bearer_flow_ctl(dev, itm, qos); } else if (itm->grant_size == 0 && tx_status && !itm->rat_switch) { itm->grant_size = DEFAULT_GRANT; Loading
core/qmi_rmnet.c +126 −9 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <linux/rtnetlink.h> #include <uapi/linux/rtnetlink.h> #include <net/pkt_sched.h> #include <net/tcp.h> #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/ip.h> Loading Loading @@ -53,6 +54,7 @@ unsigned int rmnet_wq_frequency __read_mostly = 1000; 1 : rmnet_wq_frequency/10) * (HZ/100)) #define NO_DELAY (0x0000 * HZ) #define PS_INTERVAL_KT (ms_to_ktime(1000)) #define WATCHDOG_EXPIRE_JF (msecs_to_jiffies(50)) #ifdef CONFIG_QTI_QMI_DFC static unsigned int qmi_rmnet_scale_factor = 5; Loading Loading @@ -233,6 +235,89 @@ static void qmi_rmnet_reset_txq(struct net_device *dev, unsigned int txq) } } /** * qmi_rmnet_watchdog_fn - watchdog timer func */ static void qmi_rmnet_watchdog_fn(struct timer_list *t) { struct rmnet_bearer_map *bearer; bearer = container_of(t, struct rmnet_bearer_map, watchdog); trace_dfc_watchdog(bearer->qos->mux_id, bearer->bearer_id, 2); spin_lock_bh(&bearer->qos->qos_lock); if (bearer->watchdog_quit) goto done; /* * Possible stall, try to recover. Enable 80% query and jumpstart * the bearer if disabled. */ bearer->watchdog_expire_cnt++; bearer->bytes_in_flight = 0; if (!bearer->grant_size) { bearer->grant_size = DEFAULT_CALL_GRANT; bearer->grant_thresh = qmi_rmnet_grant_per(bearer->grant_size); dfc_bearer_flow_ctl(bearer->qos->vnd_dev, bearer, bearer->qos); } else { bearer->grant_thresh = qmi_rmnet_grant_per(bearer->grant_size); } done: bearer->watchdog_started = false; spin_unlock_bh(&bearer->qos->qos_lock); } /** * qmi_rmnet_watchdog_add - add the bearer to watch * Needs to be called with qos_lock */ void qmi_rmnet_watchdog_add(struct rmnet_bearer_map *bearer) { bearer->watchdog_quit = false; if (bearer->watchdog_started) return; bearer->watchdog_started = true; mod_timer(&bearer->watchdog, jiffies + WATCHDOG_EXPIRE_JF); trace_dfc_watchdog(bearer->qos->mux_id, bearer->bearer_id, 1); } /** * qmi_rmnet_watchdog_remove - remove the bearer from watch * Needs to be called with qos_lock */ void qmi_rmnet_watchdog_remove(struct rmnet_bearer_map *bearer) { bearer->watchdog_quit = true; if (!bearer->watchdog_started) return; del_timer(&bearer->watchdog); bearer->watchdog_started = false; trace_dfc_watchdog(bearer->qos->mux_id, bearer->bearer_id, 0); } /** * qmi_rmnet_bearer_clean - clean the removed bearer * Needs to be called with rtn_lock but not qos_lock */ static void qmi_rmnet_bearer_clean(struct qos_info *qos) { if (qos->removed_bearer) { qos->removed_bearer->watchdog_quit = true; del_timer_sync(&qos->removed_bearer->watchdog); kfree(qos->removed_bearer); qos->removed_bearer = NULL; } } static struct rmnet_bearer_map *__qmi_rmnet_bearer_get( struct qos_info *qos_info, u8 bearer_id) { Loading @@ -252,6 +337,8 @@ static struct rmnet_bearer_map *__qmi_rmnet_bearer_get( bearer->grant_thresh = qmi_rmnet_grant_per(bearer->grant_size); bearer->mq_idx = INVALID_MQ; bearer->ack_mq_idx = INVALID_MQ; bearer->qos = qos_info; timer_setup(&bearer->watchdog, qmi_rmnet_watchdog_fn, 0); list_add(&bearer->list, &qos_info->bearer_head); } Loading Loading @@ -287,7 +374,7 @@ static void __qmi_rmnet_bearer_put(struct net_device *dev, /* Remove from bearer map */ list_del(&bearer->list); kfree(bearer); qos_info->removed_bearer = bearer; } } Loading Loading @@ -415,6 +502,9 @@ static int qmi_rmnet_add_flow(struct net_device *dev, struct tcmsg *tcm, done: spin_unlock_bh(&qos_info->qos_lock); qmi_rmnet_bearer_clean(qos_info); return rc; } Loading Loading @@ -458,6 +548,9 @@ qmi_rmnet_del_flow(struct net_device *dev, struct tcmsg *tcm, netif_tx_wake_all_queues(dev); spin_unlock_bh(&qos_info->qos_lock); qmi_rmnet_bearer_clean(qos_info); return 0; } Loading Loading @@ -726,6 +819,8 @@ void qmi_rmnet_enable_all_flows(struct net_device *dev) bearer->tcp_bidir = false; bearer->rat_switch = false; qmi_rmnet_watchdog_remove(bearer); if (bearer->tx_off) continue; Loading Loading @@ -779,16 +874,14 @@ void qmi_rmnet_burst_fc_check(struct net_device *dev, } EXPORT_SYMBOL(qmi_rmnet_burst_fc_check); static bool qmi_rmnet_is_tcp_ack(struct sk_buff *skb) static bool _qmi_rmnet_is_tcp_ack(struct sk_buff *skb) { unsigned int len = skb->len; switch (skb->protocol) { /* TCPv4 ACKs */ case htons(ETH_P_IP): if ((ip_hdr(skb)->protocol == IPPROTO_TCP) && (ip_hdr(skb)->ihl == 5) && (len == 40 || len == 52) && (ntohs(ip_hdr(skb)->tot_len) - (ip_hdr(skb)->ihl << 2) == tcp_hdr(skb)->doff << 2) && ((tcp_flag_word(tcp_hdr(skb)) & cpu_to_be32(0x00FF0000)) == TCP_FLAG_ACK)) return true; Loading @@ -797,7 +890,8 @@ static bool qmi_rmnet_is_tcp_ack(struct sk_buff *skb) /* TCPv6 ACKs */ case htons(ETH_P_IPV6): if ((ipv6_hdr(skb)->nexthdr == IPPROTO_TCP) && (len == 60 || len == 72) && (ntohs(ipv6_hdr(skb)->payload_len) == (tcp_hdr(skb)->doff) << 2) && ((tcp_flag_word(tcp_hdr(skb)) & cpu_to_be32(0x00FF0000)) == TCP_FLAG_ACK)) return true; Loading @@ -807,6 +901,19 @@ static bool qmi_rmnet_is_tcp_ack(struct sk_buff *skb) return false; } static inline bool qmi_rmnet_is_tcp_ack(struct sk_buff *skb) { /* Locally generated TCP acks */ if (skb_is_tcp_pure_ack(skb)) return true; /* Forwarded */ if (unlikely(_qmi_rmnet_is_tcp_ack(skb))) return true; return false; } static int qmi_rmnet_get_queue_sa(struct qos_info *qos, struct sk_buff *skb) { struct rmnet_flow_map *itm; Loading Loading @@ -873,7 +980,8 @@ inline unsigned int qmi_rmnet_grant_per(unsigned int grant) } EXPORT_SYMBOL(qmi_rmnet_grant_per); void *qmi_rmnet_qos_init(struct net_device *real_dev, u8 mux_id) void *qmi_rmnet_qos_init(struct net_device *real_dev, struct net_device *vnd_dev, u8 mux_id) { struct qos_info *qos; Loading @@ -883,6 +991,7 @@ void *qmi_rmnet_qos_init(struct net_device *real_dev, u8 mux_id) qos->mux_id = mux_id; qos->real_dev = real_dev; qos->vnd_dev = vnd_dev; qos->tran_num = 0; INIT_LIST_HEAD(&qos->flow_head); INIT_LIST_HEAD(&qos->bearer_head); Loading @@ -894,10 +1003,18 @@ EXPORT_SYMBOL(qmi_rmnet_qos_init); void qmi_rmnet_qos_exit_pre(void *qos) { struct qos_info *qosi = (struct qos_info *)qos; struct rmnet_bearer_map *bearer; if (!qos) return; list_add(&((struct qos_info *)qos)->list, &qos_cleanup_list); list_for_each_entry(bearer, &qosi->bearer_head, list) { bearer->watchdog_quit = true; del_timer_sync(&bearer->watchdog); } list_add(&qosi->list, &qos_cleanup_list); } EXPORT_SYMBOL(qmi_rmnet_qos_exit_pre); Loading
core/qmi_rmnet.h +4 −2 Original line number Diff line number Diff line Loading @@ -55,7 +55,8 @@ qmi_rmnet_all_flows_enabled(struct net_device *dev) #endif #ifdef CONFIG_QTI_QMI_DFC void *qmi_rmnet_qos_init(struct net_device *real_dev, u8 mux_id); void *qmi_rmnet_qos_init(struct net_device *real_dev, struct net_device *vnd_dev, u8 mux_id); void qmi_rmnet_qos_exit_pre(void *qos); void qmi_rmnet_qos_exit_post(void); void qmi_rmnet_burst_fc_check(struct net_device *dev, Loading @@ -63,7 +64,8 @@ void qmi_rmnet_burst_fc_check(struct net_device *dev, int qmi_rmnet_get_queue(struct net_device *dev, struct sk_buff *skb); #else static inline void * qmi_rmnet_qos_init(struct net_device *real_dev, u8 mux_id) qmi_rmnet_qos_init(struct net_device *real_dev, struct net_device *vnd_dev, u8 mux_id) { return NULL; } Loading