diff options
Diffstat (limited to 'net/llc')
-rw-r--r-- | net/llc/llc_station.c | 87 |
1 files changed, 6 insertions, 81 deletions
diff --git a/net/llc/llc_station.c b/net/llc/llc_station.c index 917d700791ba..3bdb888f8501 100644 --- a/net/llc/llc_station.c +++ b/net/llc/llc_station.c | |||
@@ -32,14 +32,9 @@ | |||
32 | * | 32 | * |
33 | * @mac_sa: MAC source address | 33 | * @mac_sa: MAC source address |
34 | * @sap_list: list of related SAPs | 34 | * @sap_list: list of related SAPs |
35 | * @ev_q: events entering state mach. | ||
36 | * @mac_pdu_q: PDUs ready to send to MAC | 35 | * @mac_pdu_q: PDUs ready to send to MAC |
37 | */ | 36 | */ |
38 | struct llc_station { | 37 | struct llc_station { |
39 | struct { | ||
40 | struct sk_buff_head list; | ||
41 | spinlock_t lock; | ||
42 | } ev_q; | ||
43 | struct sk_buff_head mac_pdu_q; | 38 | struct sk_buff_head mac_pdu_q; |
44 | }; | 39 | }; |
45 | 40 | ||
@@ -216,79 +211,6 @@ static struct llc_station_state_trans * | |||
216 | } | 211 | } |
217 | 212 | ||
218 | /** | 213 | /** |
219 | * llc_station_free_ev - frees an event | ||
220 | * @skb: Address of the event | ||
221 | * | ||
222 | * Frees an event. | ||
223 | */ | ||
224 | static void llc_station_free_ev(struct sk_buff *skb) | ||
225 | { | ||
226 | kfree_skb(skb); | ||
227 | } | ||
228 | |||
229 | /** | ||
230 | * llc_station_next_state - processes event and goes to the next state | ||
231 | * @skb: Address of the event | ||
232 | * | ||
233 | * Processes an event, executes any transitions related to that event and | ||
234 | * updates the state of the station. | ||
235 | */ | ||
236 | static u16 llc_station_next_state(struct sk_buff *skb) | ||
237 | { | ||
238 | u16 rc = 1; | ||
239 | struct llc_station_state_trans *trans; | ||
240 | |||
241 | trans = llc_find_station_trans(skb); | ||
242 | if (trans) | ||
243 | /* got the state to which we next transition; perform the | ||
244 | * actions associated with this transition before actually | ||
245 | * transitioning to the next state | ||
246 | */ | ||
247 | rc = llc_exec_station_trans_actions(trans, skb); | ||
248 | else | ||
249 | /* event not recognized in current state; re-queue it for | ||
250 | * processing again at a later time; return failure | ||
251 | */ | ||
252 | rc = 0; | ||
253 | llc_station_free_ev(skb); | ||
254 | return rc; | ||
255 | } | ||
256 | |||
257 | /** | ||
258 | * llc_station_service_events - service events in the queue | ||
259 | * | ||
260 | * Get an event from the station event queue (if any); attempt to service | ||
261 | * the event; if event serviced, get the next event (if any) on the event | ||
262 | * queue; if event not service, re-queue the event on the event queue and | ||
263 | * attempt to service the next event; when serviced all events in queue, | ||
264 | * finished; if don't transition to different state, just service all | ||
265 | * events once; if transition to new state, service all events again. | ||
266 | * Caller must hold llc_main_station.ev_q.lock. | ||
267 | */ | ||
268 | static void llc_station_service_events(void) | ||
269 | { | ||
270 | struct sk_buff *skb; | ||
271 | |||
272 | while ((skb = skb_dequeue(&llc_main_station.ev_q.list)) != NULL) | ||
273 | llc_station_next_state(skb); | ||
274 | } | ||
275 | |||
276 | /** | ||
277 | * llc_station_state_process - queue event and try to process queue. | ||
278 | * @skb: Address of the event | ||
279 | * | ||
280 | * Queues an event (on the station event queue) for handling by the | ||
281 | * station state machine and attempts to process any queued-up events. | ||
282 | */ | ||
283 | static void llc_station_state_process(struct sk_buff *skb) | ||
284 | { | ||
285 | spin_lock_bh(&llc_main_station.ev_q.lock); | ||
286 | skb_queue_tail(&llc_main_station.ev_q.list, skb); | ||
287 | llc_station_service_events(); | ||
288 | spin_unlock_bh(&llc_main_station.ev_q.lock); | ||
289 | } | ||
290 | |||
291 | /** | ||
292 | * llc_station_rcv - send received pdu to the station state machine | 214 | * llc_station_rcv - send received pdu to the station state machine |
293 | * @skb: received frame. | 215 | * @skb: received frame. |
294 | * | 216 | * |
@@ -296,14 +218,17 @@ static void llc_station_state_process(struct sk_buff *skb) | |||
296 | */ | 218 | */ |
297 | static void llc_station_rcv(struct sk_buff *skb) | 219 | static void llc_station_rcv(struct sk_buff *skb) |
298 | { | 220 | { |
299 | llc_station_state_process(skb); | 221 | struct llc_station_state_trans *trans; |
222 | |||
223 | trans = llc_find_station_trans(skb); | ||
224 | if (trans) | ||
225 | llc_exec_station_trans_actions(trans, skb); | ||
226 | kfree_skb(skb); | ||
300 | } | 227 | } |
301 | 228 | ||
302 | void __init llc_station_init(void) | 229 | void __init llc_station_init(void) |
303 | { | 230 | { |
304 | skb_queue_head_init(&llc_main_station.mac_pdu_q); | 231 | skb_queue_head_init(&llc_main_station.mac_pdu_q); |
305 | skb_queue_head_init(&llc_main_station.ev_q.list); | ||
306 | spin_lock_init(&llc_main_station.ev_q.lock); | ||
307 | llc_set_station_handler(llc_station_rcv); | 232 | llc_set_station_handler(llc_station_rcv); |
308 | } | 233 | } |
309 | 234 | ||