diff options
| author | Harout Hedeshian <harouth@codeaurora.org> | 2014-12-09 09:06:09 -0700 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-22 11:05:26 -0700 |
| commit | 6734942a8de3c58c3f77b259247a30aecbdcd106 (patch) | |
| tree | 495630f829a49b791da6df8f47ea6fc01e152767 | |
| parent | 6ec986478d6bb9a960a119ea106cdaf04cebfb80 (diff) | |
net: rmnet_data: Handle VND level MAP flow control with flow ID 0xFFFFFFFF
Flow control the entire RmNet Data virtual network device whenever
we receive a MAP flow control command with flow ID 0xFFFFFFFF. Since
it is guaranteed that we will never mix 0xFFFFFFFF with other flow IDs
(e.g.. disable 0xFFFFFFFF enable 0x00000001), TC based flow control
is not required. Instead netif stop/wake queue APIs are used in immediate
context.
CRs-Fixed: 767337
Change-Id: I8eff0988fa38726284789b70e045cc4b1dbb5d4e
Signed-off-by: Harout Hedeshian <harouth@codeaurora.org>
| -rw-r--r-- | net/rmnet_data/rmnet_data_vnd.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/net/rmnet_data/rmnet_data_vnd.c b/net/rmnet_data/rmnet_data_vnd.c index 8013165bc57d..193ef8160962 100644 --- a/net/rmnet_data/rmnet_data_vnd.c +++ b/net/rmnet_data/rmnet_data_vnd.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -61,6 +61,7 @@ struct rmnet_vnd_private_s { rwlock_t flow_map_lock; struct list_head flow_head; + struct rmnet_map_flow_mapping_s root_flow; }; #define RMNET_VND_FC_QUEUED 0 @@ -1024,6 +1025,11 @@ int rmnet_vnd_do_flow_control(struct net_device *dev, BUG(); read_lock(&dev_conf->flow_map_lock); + if (map_flow_id == 0xFFFFFFFF) { + itm = &(dev_conf->root_flow); + goto nolookup; + } + itm = _rmnet_vnd_get_flow_map(dev_conf, map_flow_id); if (!itm) { @@ -1031,8 +1037,23 @@ int rmnet_vnd_do_flow_control(struct net_device *dev, map_flow_id); goto fcdone; } + +nolookup: if (v4_seq == 0 || v4_seq >= atomic_read(&(itm->v4_seq))) { atomic_set(&(itm->v4_seq), v4_seq); + if (map_flow_id == 0xFFFFFFFF) { + LOGD("Setting VND TX queue state to %d", enable); + /* Although we expect similar number of enable/disable + * commands, optimize for the disable. That is more + * latency sensitive than enable + */ + if (unlikely(enable)) + netif_wake_queue(dev); + else + netif_stop_queue(dev); + trace_rmnet_fc_map(0xFFFFFFFF, 0, enable); + goto fcdone; + } for (i = 0; i < RMNET_MAP_FLOW_NUM_TC_HANDLE; i++) { if (itm->tc_flow_valid[i] == 1) { LOGD("Found [%s][0x%08X][%d:0x%08X]", |
