Lines Matching +full:mux +full:- +full:ctrl +full:- +full:list
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) ST-Ericsson AB 2010
44 static void cfmuxl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
54 this->layer.receive = cfmuxl_receive; in cfmuxl_create()
55 this->layer.transmit = cfmuxl_transmit; in cfmuxl_create()
56 this->layer.ctrlcmd = cfmuxl_ctrlcmd; in cfmuxl_create()
57 INIT_LIST_HEAD(&this->srvl_list); in cfmuxl_create()
58 INIT_LIST_HEAD(&this->frml_list); in cfmuxl_create()
59 spin_lock_init(&this->transmit_lock); in cfmuxl_create()
60 spin_lock_init(&this->receive_lock); in cfmuxl_create()
61 snprintf(this->layer.name, CAIF_LAYER_NAME_SZ, "mux"); in cfmuxl_create()
62 return &this->layer; in cfmuxl_create()
69 spin_lock_bh(&muxl->transmit_lock); in cfmuxl_set_dnlayer()
70 list_add_rcu(&dn->node, &muxl->frml_list); in cfmuxl_set_dnlayer()
71 spin_unlock_bh(&muxl->transmit_lock); in cfmuxl_set_dnlayer()
75 static struct cflayer *get_from_id(struct list_head *list, u16 id) in get_from_id() argument
78 list_for_each_entry_rcu(lyr, list, node) { in get_from_id()
79 if (lyr->id == id) in get_from_id()
91 spin_lock_bh(&muxl->receive_lock); in cfmuxl_set_uplayer()
93 /* Two entries with same id is wrong, so remove old layer from mux */ in cfmuxl_set_uplayer()
94 old = get_from_id(&muxl->srvl_list, linkid); in cfmuxl_set_uplayer()
96 list_del_rcu(&old->node); in cfmuxl_set_uplayer()
98 list_add_rcu(&up->node, &muxl->srvl_list); in cfmuxl_set_uplayer()
99 spin_unlock_bh(&muxl->receive_lock); in cfmuxl_set_uplayer()
110 spin_lock_bh(&muxl->transmit_lock); in cfmuxl_remove_dnlayer()
111 RCU_INIT_POINTER(muxl->dn_cache[idx], NULL); in cfmuxl_remove_dnlayer()
112 dn = get_from_id(&muxl->frml_list, phyid); in cfmuxl_remove_dnlayer()
116 list_del_rcu(&dn->node); in cfmuxl_remove_dnlayer()
119 spin_unlock_bh(&muxl->transmit_lock); in cfmuxl_remove_dnlayer()
127 up = rcu_dereference(muxl->up_cache[idx]); in get_up()
128 if (up == NULL || up->id != id) { in get_up()
129 spin_lock_bh(&muxl->receive_lock); in get_up()
130 up = get_from_id(&muxl->srvl_list, id); in get_up()
131 rcu_assign_pointer(muxl->up_cache[idx], up); in get_up()
132 spin_unlock_bh(&muxl->receive_lock); in get_up()
140 int idx = dev_info->id % DN_CACHE_SIZE; in get_dn()
141 dn = rcu_dereference(muxl->dn_cache[idx]); in get_dn()
142 if (dn == NULL || dn->id != dev_info->id) { in get_dn()
143 spin_lock_bh(&muxl->transmit_lock); in get_dn()
144 dn = get_from_id(&muxl->frml_list, dev_info->id); in get_dn()
145 rcu_assign_pointer(muxl->dn_cache[idx], dn); in get_dn()
146 spin_unlock_bh(&muxl->transmit_lock); in get_dn()
162 spin_lock_bh(&muxl->receive_lock); in cfmuxl_remove_uplayer()
163 up = get_from_id(&muxl->srvl_list, id); in cfmuxl_remove_uplayer()
167 RCU_INIT_POINTER(muxl->up_cache[idx], NULL); in cfmuxl_remove_uplayer()
168 list_del_rcu(&up->node); in cfmuxl_remove_uplayer()
170 spin_unlock_bh(&muxl->receive_lock); in cfmuxl_remove_uplayer()
183 return -EPROTO; in cfmuxl_receive()
205 ret = up->receive(up, pkt); in cfmuxl_receive()
222 dn = get_dn(muxl, info->dev_info); in cfmuxl_transmit()
225 info->dev_info->id, info->dev_info->id); in cfmuxl_transmit()
228 return -ENOTCONN; in cfmuxl_transmit()
231 info->hdr_len += 1; in cfmuxl_transmit()
232 linkid = info->channel_id; in cfmuxl_transmit()
240 err = dn->transmit(dn, pkt); in cfmuxl_transmit()
246 static void cfmuxl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, in cfmuxl_ctrlcmd() argument
253 list_for_each_entry_rcu(layer, &muxl->srvl_list, node) { in cfmuxl_ctrlcmd()
255 if (cfsrvl_phyid_match(layer, phyid) && layer->ctrlcmd) { in cfmuxl_ctrlcmd()
257 if ((ctrl == _CAIF_CTRLCMD_PHYIF_DOWN_IND || in cfmuxl_ctrlcmd()
258 ctrl == CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND) && in cfmuxl_ctrlcmd()
259 layer->id != 0) in cfmuxl_ctrlcmd()
260 cfmuxl_remove_uplayer(layr, layer->id); in cfmuxl_ctrlcmd()
263 layer->ctrlcmd(layer, ctrl, phyid); in cfmuxl_ctrlcmd()