blob: 5f185c7d5cc85d78e2c2b1bc619e76cd784255cc [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#define DEBUG
14
15#include <linux/slab.h>
16#include <linux/module.h>
17#include <linux/kernel.h>
18#include <linux/string.h>
19#include <linux/errno.h>
20#include <linux/init.h>
21#include <linux/types.h>
22#include <linux/delay.h>
23#include <linux/err.h>
24#include <linux/sched.h>
25#include <linux/poll.h>
26#include <linux/wakelock.h>
27#include <linux/platform_device.h>
28#include <linux/uaccess.h>
29#include <linux/debugfs.h>
30
31#include <asm/uaccess.h>
32#include <asm/byteorder.h>
33
34#include <mach/smem_log.h>
35
36#include "ipc_router.h"
37
38enum {
39 SMEM_LOG = 1U << 0,
40 RTR_DBG = 1U << 1,
41 R2R_MSG = 1U << 2,
42 R2R_RAW = 1U << 3,
43 NTFY_MSG = 1U << 4,
44 R2R_RAW_HDR = 1U << 5,
45};
46
47static int msm_ipc_router_debug_mask;
48module_param_named(debug_mask, msm_ipc_router_debug_mask,
49 int, S_IRUGO | S_IWUSR | S_IWGRP);
50
51#define DIAG(x...) pr_info("[RR] ERROR " x)
52
53#if defined(DEBUG)
54#define D(x...) do { \
55if (msm_ipc_router_debug_mask & RTR_DBG) \
56 pr_info(x); \
57} while (0)
58
59#define RR(x...) do { \
60if (msm_ipc_router_debug_mask & R2R_MSG) \
61 pr_info("[RR] "x); \
62} while (0)
63
64#define RAW(x...) do { \
65if (msm_ipc_router_debug_mask & R2R_RAW) \
66 pr_info("[RAW] "x); \
67} while (0)
68
69#define NTFY(x...) do { \
70if (msm_ipc_router_debug_mask & NTFY_MSG) \
71 pr_info("[NOTIFY] "x); \
72} while (0)
73
74#define RAW_HDR(x...) do { \
75if (msm_ipc_router_debug_mask & R2R_RAW_HDR) \
76 pr_info("[HDR] "x); \
77} while (0)
78#else
79#define D(x...) do { } while (0)
80#define RR(x...) do { } while (0)
81#define RAW(x...) do { } while (0)
82#define RAW_HDR(x...) do { } while (0)
83#define NTFY(x...) do { } while (0)
84#endif
85
86#define IPC_ROUTER_LOG_EVENT_ERROR 0x10
87#define IPC_ROUTER_LOG_EVENT_TX 0x11
88#define IPC_ROUTER_LOG_EVENT_RX 0x12
89
90static LIST_HEAD(control_ports);
91static DEFINE_MUTEX(control_ports_lock);
92
93#define LP_HASH_SIZE 32
94static struct list_head local_ports[LP_HASH_SIZE];
95static DEFINE_MUTEX(local_ports_lock);
96
97#define SRV_HASH_SIZE 32
98static struct list_head server_list[SRV_HASH_SIZE];
99static DEFINE_MUTEX(server_list_lock);
100static wait_queue_head_t newserver_wait;
101
102struct msm_ipc_server {
103 struct list_head list;
104 struct msm_ipc_port_name name;
105 struct list_head server_port_list;
106};
107
108struct msm_ipc_server_port {
109 struct list_head list;
110 struct msm_ipc_port_addr server_addr;
111};
112
113#define RP_HASH_SIZE 32
114struct msm_ipc_router_remote_port {
115 struct list_head list;
116 uint32_t node_id;
117 uint32_t port_id;
118 wait_queue_head_t quota_wait;
119 uint32_t tx_quota_cnt;
120 struct mutex quota_lock;
121};
122
123struct msm_ipc_router_xprt_info {
124 struct list_head list;
125 struct msm_ipc_router_xprt *xprt;
126 uint32_t remote_node_id;
127 uint32_t initialized;
128 struct list_head pkt_list;
129 wait_queue_head_t read_wait;
130 struct wake_lock wakelock;
131 struct mutex rx_lock;
132 struct mutex tx_lock;
133 uint32_t need_len;
134 struct work_struct read_data;
135 struct workqueue_struct *workqueue;
136};
137
138#define RT_HASH_SIZE 4
139struct msm_ipc_routing_table_entry {
140 struct list_head list;
141 uint32_t node_id;
142 struct list_head remote_port_list[RP_HASH_SIZE];
143 struct msm_ipc_router_xprt_info *xprt_info;
144 struct mutex lock;
145 unsigned long num_tx_bytes;
146 unsigned long num_rx_bytes;
147};
148
149static struct list_head routing_table[RT_HASH_SIZE];
150static DEFINE_MUTEX(routing_table_lock);
151static int routing_table_inited;
152
153static LIST_HEAD(msm_ipc_board_dev_list);
154static DEFINE_MUTEX(msm_ipc_board_dev_list_lock);
155
156static void do_read_data(struct work_struct *work);
157
158#define RR_STATE_IDLE 0
159#define RR_STATE_HEADER 1
160#define RR_STATE_BODY 2
161#define RR_STATE_ERROR 3
162
163#define RESTART_NORMAL 0
164#define RESTART_PEND_SVR 1
165#define RESTART_PEND_NTFY 2
166#define RESTART_PEND_NTFY_SVR 3
167
168/* State for remote ep following restart */
169#define RESTART_QUOTA_ABORT 1
170
171static LIST_HEAD(xprt_info_list);
172static DEFINE_MUTEX(xprt_info_list_lock);
173
174DECLARE_COMPLETION(msm_ipc_remote_router_up);
175
176static uint32_t next_port_id;
177static DEFINE_MUTEX(next_port_id_lock);
178
179enum {
180 CLIENT_PORT,
181 SERVER_PORT,
182 CONTROL_PORT,
183};
184
185enum {
186 DOWN,
187 UP,
188};
189
190static void init_routing_table(void)
191{
192 int i;
193 for (i = 0; i < RT_HASH_SIZE; i++)
194 INIT_LIST_HEAD(&routing_table[i]);
195}
196
197static struct msm_ipc_routing_table_entry *alloc_routing_table_entry(
198 uint32_t node_id)
199{
200 int i;
201 struct msm_ipc_routing_table_entry *rt_entry;
202
203 rt_entry = kmalloc(sizeof(struct msm_ipc_routing_table_entry),
204 GFP_KERNEL);
205 if (!rt_entry) {
206 pr_err("%s: rt_entry allocation failed for %d\n",
207 __func__, node_id);
208 return NULL;
209 }
210
211 for (i = 0; i < RP_HASH_SIZE; i++)
212 INIT_LIST_HEAD(&rt_entry->remote_port_list[i]);
213
214 mutex_init(&rt_entry->lock);
215 rt_entry->node_id = node_id;
216 rt_entry->xprt_info = NULL;
217 return rt_entry;
218}
219
220/*Please take routing_table_lock before calling this function*/
221static int add_routing_table_entry(
222 struct msm_ipc_routing_table_entry *rt_entry)
223{
224 uint32_t key;
225
226 if (!rt_entry)
227 return -EINVAL;
228
229 key = (rt_entry->node_id % RT_HASH_SIZE);
230 list_add_tail(&rt_entry->list, &routing_table[key]);
231 return 0;
232}
233
234/*Please take routing_table_lock before calling this function*/
235static struct msm_ipc_routing_table_entry *lookup_routing_table(
236 uint32_t node_id)
237{
238 uint32_t key = (node_id % RT_HASH_SIZE);
239 struct msm_ipc_routing_table_entry *rt_entry;
240
241 list_for_each_entry(rt_entry, &routing_table[key], list) {
242 if (rt_entry->node_id == node_id)
243 return rt_entry;
244 }
245 return NULL;
246}
247
248struct rr_packet *rr_read(struct msm_ipc_router_xprt_info *xprt_info)
249{
250 struct rr_packet *temp_pkt;
251
252 if (!xprt_info)
253 return NULL;
254
255 mutex_lock(&xprt_info->rx_lock);
256 while (list_empty(&xprt_info->pkt_list)) {
257 mutex_unlock(&xprt_info->rx_lock);
258 wait_event(xprt_info->read_wait,
259 !list_empty(&xprt_info->pkt_list));
260 mutex_lock(&xprt_info->rx_lock);
261 }
262 temp_pkt = list_first_entry(&xprt_info->pkt_list,
263 struct rr_packet, list);
264 list_del(&temp_pkt->list);
265 if (list_empty(&xprt_info->pkt_list))
266 wake_unlock(&xprt_info->wakelock);
267 mutex_unlock(&xprt_info->rx_lock);
268 return temp_pkt;
269}
270
271struct rr_packet *clone_pkt(struct rr_packet *pkt)
272{
273 struct rr_packet *cloned_pkt;
274 struct sk_buff *temp_skb, *cloned_skb;
275 struct sk_buff_head *pkt_fragment_q;
276
277 cloned_pkt = kzalloc(sizeof(struct rr_packet), GFP_KERNEL);
278 if (!cloned_pkt) {
279 pr_err("%s: failure\n", __func__);
280 return NULL;
281 }
282
283 pkt_fragment_q = kmalloc(sizeof(struct sk_buff_head), GFP_KERNEL);
284 if (!pkt_fragment_q) {
285 pr_err("%s: pkt_frag_q alloc failure\n", __func__);
286 kfree(cloned_pkt);
287 return NULL;
288 }
289 skb_queue_head_init(pkt_fragment_q);
290
291 skb_queue_walk(pkt->pkt_fragment_q, temp_skb) {
292 cloned_skb = skb_clone(temp_skb, GFP_KERNEL);
293 if (!cloned_skb)
294 goto fail_clone;
295 skb_queue_tail(pkt_fragment_q, cloned_skb);
296 }
297 cloned_pkt->pkt_fragment_q = pkt_fragment_q;
298 cloned_pkt->length = pkt->length;
299 return cloned_pkt;
300
301fail_clone:
302 while (!skb_queue_empty(pkt_fragment_q)) {
303 temp_skb = skb_dequeue(pkt_fragment_q);
304 kfree_skb(temp_skb);
305 }
306 kfree(pkt_fragment_q);
307 kfree(cloned_pkt);
308 return NULL;
309}
310
311struct rr_packet *create_pkt(struct sk_buff_head *data)
312{
313 struct rr_packet *pkt;
314 struct sk_buff *temp_skb;
315
316 pkt = kzalloc(sizeof(struct rr_packet), GFP_KERNEL);
317 if (!pkt) {
318 pr_err("%s: failure\n", __func__);
319 return NULL;
320 }
321
322 pkt->pkt_fragment_q = data;
323 skb_queue_walk(pkt->pkt_fragment_q, temp_skb)
324 pkt->length += temp_skb->len;
325 return pkt;
326}
327
328void release_pkt(struct rr_packet *pkt)
329{
330 struct sk_buff *temp_skb;
331
332 if (!pkt)
333 return;
334
335 if (!pkt->pkt_fragment_q) {
336 kfree(pkt);
337 return;
338 }
339
340 while (!skb_queue_empty(pkt->pkt_fragment_q)) {
341 temp_skb = skb_dequeue(pkt->pkt_fragment_q);
342 kfree_skb(temp_skb);
343 }
344 kfree(pkt->pkt_fragment_q);
345 kfree(pkt);
346 return;
347}
348
349static int post_control_ports(struct rr_packet *pkt)
350{
351 struct msm_ipc_port *port_ptr;
352 struct rr_packet *cloned_pkt;
353
354 if (!pkt)
355 return -EINVAL;
356
357 mutex_lock(&control_ports_lock);
358 list_for_each_entry(port_ptr, &control_ports, list) {
359 mutex_lock(&port_ptr->port_rx_q_lock);
360 cloned_pkt = clone_pkt(pkt);
361 wake_lock(&port_ptr->port_rx_wake_lock);
362 list_add_tail(&cloned_pkt->list, &port_ptr->port_rx_q);
363 wake_up(&port_ptr->port_rx_wait_q);
364 mutex_unlock(&port_ptr->port_rx_q_lock);
365 }
366 mutex_unlock(&control_ports_lock);
367 return 0;
368}
369
370static uint32_t allocate_port_id(void)
371{
372 uint32_t port_id = 0, prev_port_id, key;
373 struct msm_ipc_port *port_ptr;
374
375 mutex_lock(&next_port_id_lock);
376 prev_port_id = next_port_id;
377 mutex_lock(&local_ports_lock);
378 do {
379 next_port_id++;
380 if ((next_port_id & 0xFFFFFFFE) == 0xFFFFFFFE)
381 next_port_id = 1;
382
383 key = (next_port_id & (LP_HASH_SIZE - 1));
384 if (list_empty(&local_ports[key])) {
385 port_id = next_port_id;
386 break;
387 }
388 list_for_each_entry(port_ptr, &local_ports[key], list) {
389 if (port_ptr->this_port.port_id == next_port_id) {
390 port_id = next_port_id;
391 break;
392 }
393 }
394 if (!port_id) {
395 port_id = next_port_id;
396 break;
397 }
398 port_id = 0;
399 } while (next_port_id != prev_port_id);
400 mutex_unlock(&local_ports_lock);
401 mutex_unlock(&next_port_id_lock);
402
403 return port_id;
404}
405
406void msm_ipc_router_add_local_port(struct msm_ipc_port *port_ptr)
407{
408 uint32_t key;
409
410 if (!port_ptr)
411 return;
412
413 key = (port_ptr->this_port.port_id & (LP_HASH_SIZE - 1));
414 mutex_lock(&local_ports_lock);
415 list_add_tail(&port_ptr->list, &local_ports[key]);
416 mutex_unlock(&local_ports_lock);
417}
418
419struct msm_ipc_port *msm_ipc_router_create_raw_port(void *endpoint,
420 void (*notify)(unsigned event, void *data,
421 void *addr, void *priv),
422 void *priv)
423{
424 struct msm_ipc_port *port_ptr;
425
426 port_ptr = kzalloc(sizeof(struct msm_ipc_port), GFP_KERNEL);
427 if (!port_ptr)
428 return NULL;
429
430 port_ptr->this_port.node_id = IPC_ROUTER_NID_LOCAL;
431 port_ptr->this_port.port_id = allocate_port_id();
432 if (!port_ptr->this_port.port_id) {
433 pr_err("%s: All port ids are in use\n", __func__);
434 kfree(port_ptr);
435 return NULL;
436 }
437
438 spin_lock_init(&port_ptr->port_lock);
439 INIT_LIST_HEAD(&port_ptr->incomplete);
440 mutex_init(&port_ptr->incomplete_lock);
441 INIT_LIST_HEAD(&port_ptr->port_rx_q);
442 mutex_init(&port_ptr->port_rx_q_lock);
443 init_waitqueue_head(&port_ptr->port_rx_wait_q);
444 wake_lock_init(&port_ptr->port_rx_wake_lock,
445 WAKE_LOCK_SUSPEND, "msm_ipc_read");
446
447 port_ptr->endpoint = endpoint;
448 port_ptr->notify = notify;
449 port_ptr->priv = priv;
450
451 msm_ipc_router_add_local_port(port_ptr);
452 return port_ptr;
453}
454
455static struct msm_ipc_port *msm_ipc_router_lookup_local_port(uint32_t port_id)
456{
457 int key = (port_id & (LP_HASH_SIZE - 1));
458 struct msm_ipc_port *port_ptr;
459
460 mutex_lock(&local_ports_lock);
461 list_for_each_entry(port_ptr, &local_ports[key], list) {
462 if (port_ptr->this_port.port_id == port_id) {
463 mutex_unlock(&local_ports_lock);
464 return port_ptr;
465 }
466 }
467 mutex_unlock(&local_ports_lock);
468 return NULL;
469}
470
471static struct msm_ipc_router_remote_port *msm_ipc_router_lookup_remote_port(
472 uint32_t node_id,
473 uint32_t port_id)
474{
475 struct msm_ipc_router_remote_port *rport_ptr;
476 struct msm_ipc_routing_table_entry *rt_entry;
477 int key = (port_id & (RP_HASH_SIZE - 1));
478
479 mutex_lock(&routing_table_lock);
480 rt_entry = lookup_routing_table(node_id);
481 if (!rt_entry) {
482 mutex_unlock(&routing_table_lock);
483 pr_err("%s: Node is not up\n", __func__);
484 return NULL;
485 }
486
487 mutex_lock(&rt_entry->lock);
488 list_for_each_entry(rport_ptr,
489 &rt_entry->remote_port_list[key], list) {
490 if (rport_ptr->port_id == port_id) {
491 mutex_unlock(&rt_entry->lock);
492 mutex_unlock(&routing_table_lock);
493 return rport_ptr;
494 }
495 }
496 mutex_unlock(&rt_entry->lock);
497 mutex_unlock(&routing_table_lock);
498 return NULL;
499}
500
501static struct msm_ipc_router_remote_port *msm_ipc_router_create_remote_port(
502 uint32_t node_id,
503 uint32_t port_id)
504{
505 struct msm_ipc_router_remote_port *rport_ptr;
506 struct msm_ipc_routing_table_entry *rt_entry;
507 int key = (port_id & (RP_HASH_SIZE - 1));
508
509 mutex_lock(&routing_table_lock);
510 rt_entry = lookup_routing_table(node_id);
511 if (!rt_entry) {
512 mutex_unlock(&routing_table_lock);
513 pr_err("%s: Node is not up\n", __func__);
514 return NULL;
515 }
516
517 mutex_lock(&rt_entry->lock);
518 rport_ptr = kmalloc(sizeof(struct msm_ipc_router_remote_port),
519 GFP_KERNEL);
520 if (!rport_ptr) {
521 mutex_unlock(&rt_entry->lock);
522 mutex_unlock(&routing_table_lock);
523 pr_err("%s: Remote port alloc failed\n", __func__);
524 return NULL;
525 }
526 rport_ptr->port_id = port_id;
527 rport_ptr->node_id = node_id;
528 rport_ptr->tx_quota_cnt = 0;
529 init_waitqueue_head(&rport_ptr->quota_wait);
530 mutex_init(&rport_ptr->quota_lock);
531 list_add_tail(&rport_ptr->list,
532 &rt_entry->remote_port_list[key]);
533 mutex_unlock(&rt_entry->lock);
534 mutex_unlock(&routing_table_lock);
535 return rport_ptr;
536}
537
538static void msm_ipc_router_destroy_remote_port(
539 struct msm_ipc_router_remote_port *rport_ptr)
540{
541 uint32_t node_id;
542 struct msm_ipc_routing_table_entry *rt_entry;
543
544 if (!rport_ptr)
545 return;
546
547 node_id = rport_ptr->node_id;
548 mutex_lock(&routing_table_lock);
549 rt_entry = lookup_routing_table(node_id);
550 if (!rt_entry) {
551 mutex_unlock(&routing_table_lock);
552 pr_err("%s: Node %d is not up\n", __func__, node_id);
553 return;
554 }
555
556 mutex_lock(&rt_entry->lock);
557 list_del(&rport_ptr->list);
558 kfree(rport_ptr);
559 mutex_unlock(&rt_entry->lock);
560 mutex_unlock(&routing_table_lock);
561 return;
562}
563
564static struct msm_ipc_server *msm_ipc_router_lookup_server(
565 uint32_t service,
566 uint32_t instance,
567 uint32_t node_id,
568 uint32_t port_id)
569{
570 struct msm_ipc_server *server;
571 struct msm_ipc_server_port *server_port;
572 int key = (instance & (SRV_HASH_SIZE - 1));
573
574 mutex_lock(&server_list_lock);
575 list_for_each_entry(server, &server_list[key], list) {
576 if ((server->name.service != service) ||
577 (server->name.instance != instance))
578 continue;
579 if ((node_id == 0) && (port_id == 0)) {
580 mutex_unlock(&server_list_lock);
581 return server;
582 }
583 list_for_each_entry(server_port, &server->server_port_list,
584 list) {
585 if ((server_port->server_addr.node_id == node_id) &&
586 (server_port->server_addr.port_id == port_id)) {
587 mutex_unlock(&server_list_lock);
588 return server;
589 }
590 }
591 }
592 mutex_unlock(&server_list_lock);
593 return NULL;
594}
595
596static struct msm_ipc_server *msm_ipc_router_create_server(
597 uint32_t service,
598 uint32_t instance,
599 uint32_t node_id,
600 uint32_t port_id)
601{
602 struct msm_ipc_server *server = NULL;
603 struct msm_ipc_server_port *server_port;
604 int key = (instance & (SRV_HASH_SIZE - 1));
605
606 mutex_lock(&server_list_lock);
607 list_for_each_entry(server, &server_list[key], list) {
608 if ((server->name.service == service) &&
609 (server->name.instance == instance))
610 goto create_srv_port;
611 }
612
613 server = kmalloc(sizeof(struct msm_ipc_server), GFP_KERNEL);
614 if (!server) {
615 mutex_unlock(&server_list_lock);
616 pr_err("%s: Server allocation failed\n", __func__);
617 return NULL;
618 }
619 server->name.service = service;
620 server->name.instance = instance;
621 INIT_LIST_HEAD(&server->server_port_list);
622 list_add_tail(&server->list, &server_list[key]);
623
624create_srv_port:
625 server_port = kmalloc(sizeof(struct msm_ipc_server_port), GFP_KERNEL);
626 if (!server_port) {
627 if (list_empty(&server->server_port_list)) {
628 list_del(&server->list);
629 kfree(server);
630 }
631 mutex_unlock(&server_list_lock);
632 pr_err("%s: Server Port allocation failed\n", __func__);
633 return NULL;
634 }
635 server_port->server_addr.node_id = node_id;
636 server_port->server_addr.port_id = port_id;
637 list_add_tail(&server_port->list, &server->server_port_list);
638 mutex_unlock(&server_list_lock);
639
640 return server;
641}
642
643static void msm_ipc_router_destroy_server(struct msm_ipc_server *server,
644 uint32_t node_id, uint32_t port_id)
645{
646 struct msm_ipc_server_port *server_port;
647
648 if (!server)
649 return;
650
651 mutex_lock(&server_list_lock);
652 list_for_each_entry(server_port, &server->server_port_list, list) {
653 if ((server_port->server_addr.node_id == node_id) &&
654 (server_port->server_addr.port_id == port_id))
655 break;
656 }
657 if (server_port) {
658 list_del(&server_port->list);
659 kfree(server_port);
660 }
661 if (list_empty(&server->server_port_list)) {
662 list_del(&server->list);
663 kfree(server);
664 }
665 mutex_unlock(&server_list_lock);
666 return;
667}
668
669static int msm_ipc_router_send_control_msg(
670 struct msm_ipc_router_xprt_info *xprt_info,
671 union rr_control_msg *msg)
672{
673 struct rr_packet *pkt;
674 struct sk_buff *ipc_rtr_pkt;
675 struct rr_header *hdr;
676 int pkt_size;
677 void *data;
678 struct sk_buff_head *pkt_fragment_q;
679 int ret;
680
681 if (!xprt_info || ((msg->cmd != IPC_ROUTER_CTRL_CMD_HELLO) &&
682 !xprt_info->initialized)) {
683 pr_err("%s: xprt_info not initialized\n", __func__);
684 return -EINVAL;
685 }
686
687 if (xprt_info->remote_node_id == IPC_ROUTER_NID_LOCAL)
688 return 0;
689
690 pkt = kzalloc(sizeof(struct rr_packet), GFP_KERNEL);
691 if (!pkt) {
692 pr_err("%s: pkt alloc failed\n", __func__);
693 return -ENOMEM;
694 }
695
696 pkt_fragment_q = kmalloc(sizeof(struct sk_buff_head), GFP_KERNEL);
697 if (!pkt_fragment_q) {
698 pr_err("%s: pkt_fragment_q alloc failed\n", __func__);
699 kfree(pkt);
700 return -ENOMEM;
701 }
702 skb_queue_head_init(pkt_fragment_q);
703
704 pkt_size = IPC_ROUTER_HDR_SIZE + sizeof(*msg);
705 ipc_rtr_pkt = alloc_skb(pkt_size, GFP_KERNEL);
706 if (!ipc_rtr_pkt) {
707 pr_err("%s: ipc_rtr_pkt alloc failed\n", __func__);
708 kfree(pkt_fragment_q);
709 kfree(pkt);
710 return -ENOMEM;
711 }
712
713 skb_reserve(ipc_rtr_pkt, IPC_ROUTER_HDR_SIZE);
714 data = skb_put(ipc_rtr_pkt, sizeof(*msg));
715 memcpy(data, msg, sizeof(*msg));
716 hdr = (struct rr_header *)skb_push(ipc_rtr_pkt, IPC_ROUTER_HDR_SIZE);
717 if (!hdr) {
718 pr_err("%s: skb_push failed\n", __func__);
719 kfree_skb(ipc_rtr_pkt);
720 kfree(pkt_fragment_q);
721 kfree(pkt);
722 return -ENOMEM;
723 }
724
725 hdr->version = IPC_ROUTER_VERSION;
726 hdr->type = msg->cmd;
727 hdr->src_node_id = IPC_ROUTER_NID_LOCAL;
728 hdr->src_port_id = IPC_ROUTER_ADDRESS;
729 hdr->confirm_rx = 0;
730 hdr->size = sizeof(*msg);
731 hdr->dst_node_id = xprt_info->remote_node_id;
732 hdr->dst_port_id = IPC_ROUTER_ADDRESS;
733 skb_queue_tail(pkt_fragment_q, ipc_rtr_pkt);
734 pkt->pkt_fragment_q = pkt_fragment_q;
735 pkt->length = pkt_size;
736
737 mutex_lock(&xprt_info->tx_lock);
738 ret = xprt_info->xprt->write(pkt, pkt_size, 0);
739 mutex_unlock(&xprt_info->tx_lock);
740
741 release_pkt(pkt);
742 return ret;
743}
744
745static int msm_ipc_router_send_server_list(
746 struct msm_ipc_router_xprt_info *xprt_info)
747{
748 union rr_control_msg ctl;
749 struct msm_ipc_server *server;
750 struct msm_ipc_server_port *server_port;
751 int i;
752
753 if (!xprt_info || !xprt_info->initialized) {
754 pr_err("%s: Xprt info not initialized\n", __func__);
755 return -EINVAL;
756 }
757
758 ctl.cmd = IPC_ROUTER_CTRL_CMD_NEW_SERVER;
759
760 mutex_lock(&server_list_lock);
761 for (i = 0; i < SRV_HASH_SIZE; i++) {
762 list_for_each_entry(server, &server_list[i], list) {
763 ctl.srv.service = server->name.service;
764 ctl.srv.instance = server->name.instance;
765 list_for_each_entry(server_port,
766 &server->server_port_list, list) {
767 if (server_port->server_addr.node_id ==
768 xprt_info->remote_node_id)
769 continue;
770
771 ctl.srv.node_id =
772 server_port->server_addr.node_id;
773 ctl.srv.port_id =
774 server_port->server_addr.port_id;
775 msm_ipc_router_send_control_msg(xprt_info,
776 &ctl);
777 }
778 }
779 }
780 mutex_unlock(&server_list_lock);
781
782 return 0;
783}
784
785#if defined(DEBUG)
786static char *type_to_str(int i)
787{
788 switch (i) {
789 case IPC_ROUTER_CTRL_CMD_DATA:
790 return "data ";
791 case IPC_ROUTER_CTRL_CMD_HELLO:
792 return "hello ";
793 case IPC_ROUTER_CTRL_CMD_BYE:
794 return "bye ";
795 case IPC_ROUTER_CTRL_CMD_NEW_SERVER:
796 return "new_srvr";
797 case IPC_ROUTER_CTRL_CMD_REMOVE_SERVER:
798 return "rmv_srvr";
799 case IPC_ROUTER_CTRL_CMD_REMOVE_CLIENT:
800 return "rmv_clnt";
801 case IPC_ROUTER_CTRL_CMD_RESUME_TX:
802 return "resum_tx";
803 case IPC_ROUTER_CTRL_CMD_EXIT:
804 return "cmd_exit";
805 default:
806 return "invalid";
807 }
808}
809#endif
810
811static int broadcast_ctl_msg_locally(union rr_control_msg *msg)
812{
813 struct rr_packet *pkt;
814 struct sk_buff *ipc_rtr_pkt;
815 struct rr_header *hdr;
816 int pkt_size;
817 void *data;
818 struct sk_buff_head *pkt_fragment_q;
819 int ret;
820
821 pkt = kzalloc(sizeof(struct rr_packet), GFP_KERNEL);
822 if (!pkt) {
823 pr_err("%s: pkt alloc failed\n", __func__);
824 return -ENOMEM;
825 }
826
827 pkt_fragment_q = kmalloc(sizeof(struct sk_buff_head), GFP_KERNEL);
828 if (!pkt_fragment_q) {
829 pr_err("%s: pkt_fragment_q alloc failed\n", __func__);
830 kfree(pkt);
831 return -ENOMEM;
832 }
833 skb_queue_head_init(pkt_fragment_q);
834
835 pkt_size = IPC_ROUTER_HDR_SIZE + sizeof(*msg);
836 ipc_rtr_pkt = alloc_skb(pkt_size, GFP_KERNEL);
837 if (!ipc_rtr_pkt) {
838 pr_err("%s: ipc_rtr_pkt alloc failed\n", __func__);
839 kfree(pkt_fragment_q);
840 kfree(pkt);
841 return -ENOMEM;
842 }
843
844 skb_reserve(ipc_rtr_pkt, IPC_ROUTER_HDR_SIZE);
845 data = skb_put(ipc_rtr_pkt, sizeof(*msg));
846 memcpy(data, msg, sizeof(*msg));
847 hdr = (struct rr_header *)skb_push(ipc_rtr_pkt, IPC_ROUTER_HDR_SIZE);
848 if (!hdr) {
849 pr_err("%s: skb_push failed\n", __func__);
850 kfree_skb(ipc_rtr_pkt);
851 kfree(pkt_fragment_q);
852 kfree(pkt);
853 return -ENOMEM;
854 }
855 hdr->version = IPC_ROUTER_VERSION;
856 hdr->type = msg->cmd;
857 hdr->src_node_id = IPC_ROUTER_NID_LOCAL;
858 hdr->src_port_id = IPC_ROUTER_ADDRESS;
859 hdr->confirm_rx = 0;
860 hdr->size = sizeof(*msg);
861 hdr->dst_node_id = IPC_ROUTER_NID_LOCAL;
862 hdr->dst_port_id = IPC_ROUTER_ADDRESS;
863 skb_queue_tail(pkt_fragment_q, ipc_rtr_pkt);
864 pkt->pkt_fragment_q = pkt_fragment_q;
865 pkt->length = pkt_size;
866
867 ret = post_control_ports(pkt);
868 release_pkt(pkt);
869 return ret;
870}
871
872static int broadcast_ctl_msg(union rr_control_msg *ctl)
873{
874 struct msm_ipc_router_xprt_info *xprt_info;
875
876 mutex_lock(&xprt_info_list_lock);
877 list_for_each_entry(xprt_info, &xprt_info_list, list) {
878 msm_ipc_router_send_control_msg(xprt_info, ctl);
879 }
880 mutex_unlock(&xprt_info_list_lock);
881
882 return 0;
883}
884
885static int relay_msg(struct msm_ipc_router_xprt_info *xprt_info,
886 struct rr_packet *pkt)
887{
888 struct msm_ipc_router_xprt_info *fwd_xprt_info;
889
890 if (!xprt_info || !pkt)
891 return -EINVAL;
892
893 mutex_lock(&xprt_info_list_lock);
894 list_for_each_entry(fwd_xprt_info, &xprt_info_list, list) {
895 mutex_lock(&fwd_xprt_info->tx_lock);
896 if (xprt_info->xprt->link_id != fwd_xprt_info->xprt->link_id)
897 fwd_xprt_info->xprt->write(pkt, pkt->length, 0);
898 mutex_unlock(&fwd_xprt_info->tx_lock);
899 }
900 mutex_unlock(&xprt_info_list_lock);
901 return 0;
902}
903
904static int forward_msg(struct msm_ipc_router_xprt_info *xprt_info,
905 struct rr_packet *pkt)
906{
907 uint32_t dst_node_id;
908 struct sk_buff *head_pkt;
909 struct rr_header *hdr;
910 struct msm_ipc_router_xprt_info *fwd_xprt_info;
911 struct msm_ipc_routing_table_entry *rt_entry;
912
913 if (!xprt_info || !pkt)
914 return -EINVAL;
915
916 head_pkt = skb_peek(pkt->pkt_fragment_q);
917 if (!head_pkt)
918 return -EINVAL;
919
920 hdr = (struct rr_header *)head_pkt->data;
921 dst_node_id = hdr->dst_node_id;
922 mutex_lock(&routing_table_lock);
923 rt_entry = lookup_routing_table(dst_node_id);
924 if (!(rt_entry) || !(rt_entry->xprt_info)) {
925 mutex_unlock(&routing_table_lock);
926 pr_err("%s: Routing table not initialized\n", __func__);
927 return -ENODEV;
928 }
929
930 mutex_lock(&rt_entry->lock);
931 fwd_xprt_info = rt_entry->xprt_info;
932 mutex_lock(&fwd_xprt_info->tx_lock);
933 if (xprt_info->remote_node_id == fwd_xprt_info->remote_node_id) {
934 mutex_unlock(&fwd_xprt_info->tx_lock);
935 mutex_unlock(&rt_entry->lock);
936 mutex_unlock(&routing_table_lock);
937 pr_err("%s: Discarding Command to route back\n", __func__);
938 return -EINVAL;
939 }
940
941 if (xprt_info->xprt->link_id == fwd_xprt_info->xprt->link_id) {
942 mutex_unlock(&fwd_xprt_info->tx_lock);
943 mutex_unlock(&rt_entry->lock);
944 mutex_unlock(&routing_table_lock);
945 pr_err("%s: DST in the same cluster\n", __func__);
946 return 0;
947 }
948 fwd_xprt_info->xprt->write(pkt, pkt->length, 0);
949 mutex_unlock(&fwd_xprt_info->tx_lock);
950 mutex_unlock(&rt_entry->lock);
951 mutex_unlock(&routing_table_lock);
952
953 return 0;
954}
955
956static int process_control_msg(struct msm_ipc_router_xprt_info *xprt_info,
957 struct rr_packet *pkt)
958{
959 union rr_control_msg ctl;
960 union rr_control_msg *msg;
961 struct msm_ipc_router_remote_port *rport_ptr;
962 int rc = 0;
963 static uint32_t first = 1;
964 struct sk_buff *temp_ptr;
965 struct rr_header *hdr;
966 struct msm_ipc_server *server;
967 struct msm_ipc_routing_table_entry *rt_entry;
968
969 if (pkt->length != (IPC_ROUTER_HDR_SIZE + sizeof(*msg))) {
970 pr_err("%s: r2r msg size %d != %d\n", __func__, pkt->length,
971 (IPC_ROUTER_HDR_SIZE + sizeof(*msg)));
972 return -EINVAL;
973 }
974
975 temp_ptr = skb_peek(pkt->pkt_fragment_q);
976 hdr = (struct rr_header *)temp_ptr->data;
977 msg = (union rr_control_msg *)((char *)hdr + IPC_ROUTER_HDR_SIZE);
978
979 switch (msg->cmd) {
980 case IPC_ROUTER_CTRL_CMD_HELLO:
981 RR("o HELLO NID %d\n", hdr->src_node_id);
982 xprt_info->remote_node_id = hdr->src_node_id;
983
984 mutex_lock(&routing_table_lock);
985 rt_entry = lookup_routing_table(hdr->src_node_id);
986 if (!rt_entry) {
987 rt_entry = alloc_routing_table_entry(hdr->src_node_id);
988 if (!rt_entry) {
989 mutex_unlock(&routing_table_lock);
990 pr_err("%s: rt_entry allocation failed\n",
991 __func__);
992 return -ENOMEM;
993 }
994 }
995 mutex_lock(&rt_entry->lock);
996 rt_entry->xprt_info = xprt_info;
997 mutex_unlock(&rt_entry->lock);
998 add_routing_table_entry(rt_entry);
999 mutex_unlock(&routing_table_lock);
1000
1001 memset(&ctl, 0, sizeof(ctl));
1002 ctl.cmd = IPC_ROUTER_CTRL_CMD_HELLO;
1003 msm_ipc_router_send_control_msg(xprt_info, &ctl);
1004
1005 xprt_info->initialized = 1;
1006
1007 /* Send list of servers one at a time */
1008 msm_ipc_router_send_server_list(xprt_info);
1009
1010 if (first) {
1011 first = 0;
1012 complete_all(&msm_ipc_remote_router_up);
1013 }
1014 RR("HELLO message processed\n");
1015 break;
1016 case IPC_ROUTER_CTRL_CMD_RESUME_TX:
1017 RR("o RESUME_TX id=%d:%08x\n",
1018 msg->cli.node_id, msg->cli.port_id);
1019
1020 rport_ptr = msm_ipc_router_lookup_remote_port(msg->cli.node_id,
1021 msg->cli.port_id);
1022 if (!rport_ptr) {
1023 pr_err("%s: Unable to resume client\n", __func__);
1024 break;
1025 }
1026 mutex_lock(&rport_ptr->quota_lock);
1027 rport_ptr->tx_quota_cnt = 0;
1028 mutex_unlock(&rport_ptr->quota_lock);
1029 wake_up(&rport_ptr->quota_wait);
1030 break;
1031
1032 case IPC_ROUTER_CTRL_CMD_NEW_SERVER:
1033 if (msg->srv.instance == 0) {
1034 pr_err(
1035 "rpcrouter: Server create rejected, version = 0, "
1036 "service = %08x\n", msg->srv.service);
1037 break;
1038 }
1039
1040 RR("o NEW_SERVER id=%d:%08x service=%08x:%08x\n",
1041 msg->srv.node_id, msg->srv.port_id,
1042 msg->srv.service, msg->srv.instance);
1043
1044 mutex_lock(&routing_table_lock);
1045 rt_entry = lookup_routing_table(msg->srv.node_id);
1046 if (!rt_entry) {
1047 rt_entry = alloc_routing_table_entry(msg->srv.node_id);
1048 if (!rt_entry) {
1049 mutex_unlock(&routing_table_lock);
1050 pr_err("%s: rt_entry allocation failed\n",
1051 __func__);
1052 return -ENOMEM;
1053 }
1054 mutex_lock(&rt_entry->lock);
1055 rt_entry->xprt_info = xprt_info;
1056 mutex_unlock(&rt_entry->lock);
1057 add_routing_table_entry(rt_entry);
1058 }
1059 mutex_unlock(&routing_table_lock);
1060
1061 server = msm_ipc_router_lookup_server(msg->srv.service,
1062 msg->srv.instance,
1063 msg->srv.node_id,
1064 msg->srv.port_id);
1065 if (!server) {
1066 server = msm_ipc_router_create_server(
1067 msg->srv.service, msg->srv.instance,
1068 msg->srv.node_id, msg->srv.port_id);
1069 if (!server) {
1070 pr_err("%s: Server Create failed\n", __func__);
1071 return -ENOMEM;
1072 }
1073
1074 if (!msm_ipc_router_lookup_remote_port(
1075 msg->srv.node_id, msg->srv.port_id)) {
1076 rport_ptr = msm_ipc_router_create_remote_port(
1077 msg->srv.node_id, msg->srv.port_id);
1078 if (!rport_ptr)
1079 pr_err("%s: Remote port create "
1080 "failed\n", __func__);
1081 }
1082 wake_up(&newserver_wait);
1083 }
1084
1085 relay_msg(xprt_info, pkt);
1086 post_control_ports(pkt);
1087 break;
1088 case IPC_ROUTER_CTRL_CMD_REMOVE_SERVER:
1089 RR("o REMOVE_SERVER service=%08x:%d\n",
1090 msg->srv.service, msg->srv.instance);
1091 server = msm_ipc_router_lookup_server(msg->srv.service,
1092 msg->srv.instance,
1093 msg->srv.node_id,
1094 msg->srv.port_id);
1095 if (server) {
1096 msm_ipc_router_destroy_server(server,
1097 msg->srv.node_id,
1098 msg->srv.port_id);
1099 relay_msg(xprt_info, pkt);
1100 post_control_ports(pkt);
1101 }
1102 break;
1103 case IPC_ROUTER_CTRL_CMD_REMOVE_CLIENT:
1104 RR("o REMOVE_CLIENT id=%d:%08x\n",
1105 msg->cli.node_id, msg->cli.port_id);
1106 rport_ptr = msm_ipc_router_lookup_remote_port(msg->cli.node_id,
1107 msg->cli.port_id);
1108 if (rport_ptr)
1109 msm_ipc_router_destroy_remote_port(rport_ptr);
1110
1111 relay_msg(xprt_info, pkt);
1112 post_control_ports(pkt);
1113 break;
1114 case IPC_ROUTER_CTRL_CMD_PING:
1115 /* No action needed for ping messages received */
1116 RR("o PING\n");
1117 break;
1118 default:
1119 RR("o UNKNOWN(%08x)\n", msg->cmd);
1120 rc = -ENOSYS;
1121 }
1122
1123 return rc;
1124}
1125
1126static void do_read_data(struct work_struct *work)
1127{
1128 struct rr_header *hdr;
1129 struct rr_packet *pkt = NULL;
1130 struct msm_ipc_port *port_ptr;
1131 struct sk_buff *head_skb;
1132 struct msm_ipc_port_addr *src_addr;
1133 uint32_t resume_tx, resume_tx_node_id, resume_tx_port_id;
1134
1135 struct msm_ipc_router_xprt_info *xprt_info =
1136 container_of(work,
1137 struct msm_ipc_router_xprt_info,
1138 read_data);
1139
1140 pkt = rr_read(xprt_info);
1141 if (!pkt) {
1142 pr_err("%s: rr_read failed\n", __func__);
1143 goto fail_io;
1144 }
1145
1146 if (pkt->length < IPC_ROUTER_HDR_SIZE ||
1147 pkt->length > MAX_IPC_PKT_SIZE) {
1148 pr_err("%s: Invalid pkt length %d\n", __func__, pkt->length);
1149 goto fail_data;
1150 }
1151
1152 head_skb = skb_peek(pkt->pkt_fragment_q);
1153 if (!head_skb) {
1154 pr_err("%s: head_skb is invalid\n", __func__);
1155 goto fail_data;
1156 }
1157
1158 hdr = (struct rr_header *)(head_skb->data);
1159 RR("- ver=%d type=%d src=%d:%08x crx=%d siz=%d dst=%d:%08x\n",
1160 hdr->version, hdr->type, hdr->src_node_id, hdr->src_port_id,
1161 hdr->confirm_rx, hdr->size, hdr->dst_node_id, hdr->dst_port_id);
1162 RAW_HDR("[r rr_h] "
1163 "ver=%i,type=%s,src_node_id=%08x,src_port_id=%08x,"
1164 "confirm_rx=%i,size=%3i,dst_node_id=%08x,dst_port_id=%08x\n",
1165 hdr->version, type_to_str(hdr->type), hdr->src_node_id,
1166 hdr->src_port_id, hdr->confirm_rx, hdr->size, hdr->dst_node_id,
1167 hdr->dst_port_id);
1168
1169 if (hdr->version != IPC_ROUTER_VERSION) {
1170 pr_err("version %d != %d\n", hdr->version, IPC_ROUTER_VERSION);
1171 goto fail_data;
1172 }
1173
1174 if ((hdr->dst_node_id != IPC_ROUTER_NID_LOCAL) &&
1175 ((hdr->type == IPC_ROUTER_CTRL_CMD_RESUME_TX) ||
1176 (hdr->type == IPC_ROUTER_CTRL_CMD_DATA))) {
1177 forward_msg(xprt_info, pkt);
1178 release_pkt(pkt);
1179 goto done;
1180 }
1181
1182 if ((hdr->dst_port_id == IPC_ROUTER_ADDRESS) ||
1183 (hdr->type == IPC_ROUTER_CTRL_CMD_HELLO)) {
1184 process_control_msg(xprt_info, pkt);
1185 release_pkt(pkt);
1186 goto done;
1187 }
1188#if defined(CONFIG_MSM_SMD_LOGGING)
1189#if defined(DEBUG)
1190 if (msm_ipc_router_debug_mask & SMEM_LOG) {
1191 smem_log_event((SMEM_LOG_PROC_ID_APPS |
1192 SMEM_LOG_RPC_ROUTER_EVENT_BASE |
1193 IPC_ROUTER_LOG_EVENT_RX),
1194 (hdr->src_node_id << 24) |
1195 (hdr->src_port_id & 0xffffff),
1196 (hdr->dst_node_id << 24) |
1197 (hdr->dst_port_id & 0xffffff),
1198 (hdr->type << 24) | (hdr->confirm_rx << 16) |
1199 (hdr->size & 0xffff));
1200 }
1201#endif
1202#endif
1203
1204 resume_tx = hdr->confirm_rx;
1205 resume_tx_node_id = hdr->dst_node_id;
1206 resume_tx_port_id = hdr->dst_port_id;
1207
1208 port_ptr = msm_ipc_router_lookup_local_port(hdr->dst_port_id);
1209 if (!port_ptr) {
1210 pr_err("%s: No local port id %08x\n", __func__,
1211 hdr->dst_port_id);
1212 release_pkt(pkt);
1213 goto process_done;
1214 }
1215
1216 if (!port_ptr->notify) {
1217 mutex_lock(&port_ptr->port_rx_q_lock);
1218 wake_lock(&port_ptr->port_rx_wake_lock);
1219 list_add_tail(&pkt->list, &port_ptr->port_rx_q);
1220 wake_up(&port_ptr->port_rx_wait_q);
1221 mutex_unlock(&port_ptr->port_rx_q_lock);
1222 } else {
1223 src_addr = kmalloc(sizeof(struct msm_ipc_port_addr),
1224 GFP_KERNEL);
1225 if (src_addr) {
1226 src_addr->node_id = hdr->src_node_id;
1227 src_addr->port_id = hdr->src_port_id;
1228 }
1229 skb_pull(head_skb, IPC_ROUTER_HDR_SIZE);
1230 port_ptr->notify(MSM_IPC_ROUTER_READ_CB, pkt->pkt_fragment_q,
1231 src_addr, port_ptr->priv);
1232 pkt->pkt_fragment_q = NULL;
1233 src_addr = NULL;
1234 release_pkt(pkt);
1235 }
1236
1237process_done:
1238 if (resume_tx) {
1239 union rr_control_msg msg;
1240
1241 msg.cmd = IPC_ROUTER_CTRL_CMD_RESUME_TX;
1242 msg.cli.node_id = resume_tx_node_id;
1243 msg.cli.port_id = resume_tx_port_id;
1244
1245 RR("x RESUME_TX id=%d:%08x\n",
1246 msg.cli.node_id, msg.cli.port_id);
1247 msm_ipc_router_send_control_msg(xprt_info, &msg);
1248 }
1249
1250done:
1251 queue_work(xprt_info->workqueue, &xprt_info->read_data);
1252 return;
1253
1254fail_data:
1255 release_pkt(pkt);
1256fail_io:
1257 pr_err("ipc_router has died\n");
1258}
1259
1260int msm_ipc_router_register_server(struct msm_ipc_port *port_ptr,
1261 struct msm_ipc_addr *name)
1262{
1263 struct msm_ipc_server *server;
1264 unsigned long flags;
1265 union rr_control_msg ctl;
1266
1267 if (!port_ptr || !name)
1268 return -EINVAL;
1269
1270 if (name->addrtype != MSM_IPC_ADDR_NAME)
1271 return -EINVAL;
1272
1273 server = msm_ipc_router_lookup_server(name->addr.port_name.service,
1274 name->addr.port_name.instance,
1275 IPC_ROUTER_NID_LOCAL,
1276 port_ptr->this_port.port_id);
1277 if (server) {
1278 pr_err("%s: Server already present\n", __func__);
1279 return -EINVAL;
1280 }
1281
1282 server = msm_ipc_router_create_server(name->addr.port_name.service,
1283 name->addr.port_name.instance,
1284 IPC_ROUTER_NID_LOCAL,
1285 port_ptr->this_port.port_id);
1286 if (!server) {
1287 pr_err("%s: Server Creation failed\n", __func__);
1288 return -EINVAL;
1289 }
1290
1291 ctl.cmd = IPC_ROUTER_CTRL_CMD_NEW_SERVER;
1292 ctl.srv.service = server->name.service;
1293 ctl.srv.instance = server->name.instance;
1294 ctl.srv.node_id = IPC_ROUTER_NID_LOCAL;
1295 ctl.srv.port_id = port_ptr->this_port.port_id;
1296 broadcast_ctl_msg(&ctl);
1297 spin_lock_irqsave(&port_ptr->port_lock, flags);
1298 port_ptr->type = SERVER_PORT;
1299 port_ptr->port_name.service = server->name.service;
1300 port_ptr->port_name.instance = server->name.instance;
1301 spin_unlock_irqrestore(&port_ptr->port_lock, flags);
1302 return 0;
1303}
1304
1305int msm_ipc_router_unregister_server(struct msm_ipc_port *port_ptr)
1306{
1307 struct msm_ipc_server *server;
1308 unsigned long flags;
1309 union rr_control_msg ctl;
1310
1311 if (!port_ptr)
1312 return -EINVAL;
1313
1314 if (port_ptr->type != SERVER_PORT) {
1315 pr_err("%s: Trying to unregister a non-server port\n",
1316 __func__);
1317 return -EINVAL;
1318 }
1319
1320 if (port_ptr->this_port.node_id != IPC_ROUTER_NID_LOCAL) {
1321 pr_err("%s: Trying to unregister a remote server locally\n",
1322 __func__);
1323 return -EINVAL;
1324 }
1325
1326 server = msm_ipc_router_lookup_server(port_ptr->port_name.service,
1327 port_ptr->port_name.instance,
1328 port_ptr->this_port.node_id,
1329 port_ptr->this_port.port_id);
1330 if (!server) {
1331 pr_err("%s: Server lookup failed\n", __func__);
1332 return -ENODEV;
1333 }
1334
1335 ctl.cmd = IPC_ROUTER_CTRL_CMD_REMOVE_SERVER;
1336 ctl.srv.service = server->name.service;
1337 ctl.srv.instance = server->name.instance;
1338 ctl.srv.node_id = IPC_ROUTER_NID_LOCAL;
1339 ctl.srv.port_id = port_ptr->this_port.port_id;
1340 broadcast_ctl_msg(&ctl);
1341 msm_ipc_router_destroy_server(server, port_ptr->this_port.node_id,
1342 port_ptr->this_port.port_id);
1343 spin_lock_irqsave(&port_ptr->port_lock, flags);
1344 port_ptr->type = CLIENT_PORT;
1345 spin_unlock_irqrestore(&port_ptr->port_lock, flags);
1346 return 0;
1347}
1348
1349static int loopback_data(struct msm_ipc_port *src,
1350 uint32_t port_id,
1351 struct sk_buff_head *data)
1352{
1353 struct sk_buff *head_skb;
1354 struct rr_header *hdr;
1355 struct msm_ipc_port *port_ptr;
1356 struct rr_packet *pkt;
1357
1358 if (!data) {
1359 pr_err("%s: Invalid pkt pointer\n", __func__);
1360 return -EINVAL;
1361 }
1362
1363 pkt = create_pkt(data);
1364 if (!pkt) {
1365 pr_err("%s: New pkt create failed\n", __func__);
1366 return -ENOMEM;
1367 }
1368
1369 head_skb = skb_peek(pkt->pkt_fragment_q);
1370 hdr = (struct rr_header *)skb_push(head_skb, IPC_ROUTER_HDR_SIZE);
1371 if (!hdr) {
1372 pr_err("%s: Prepend Header failed\n", __func__);
1373 release_pkt(pkt);
1374 return -ENOMEM;
1375 }
1376 hdr->version = IPC_ROUTER_VERSION;
1377 hdr->type = IPC_ROUTER_CTRL_CMD_DATA;
1378 hdr->src_node_id = src->this_port.node_id;
1379 hdr->src_port_id = src->this_port.port_id;
1380 hdr->size = pkt->length;
1381 hdr->confirm_rx = 0;
1382 hdr->dst_node_id = IPC_ROUTER_NID_LOCAL;
1383 hdr->dst_port_id = port_id;
1384 pkt->length += IPC_ROUTER_HDR_SIZE;
1385
1386 port_ptr = msm_ipc_router_lookup_local_port(port_id);
1387 if (!port_ptr) {
1388 pr_err("%s: Local port %d not present\n", __func__, port_id);
1389 release_pkt(pkt);
1390 return -ENODEV;
1391 }
1392
1393 mutex_lock(&port_ptr->port_rx_q_lock);
1394 wake_lock(&port_ptr->port_rx_wake_lock);
1395 list_add_tail(&pkt->list, &port_ptr->port_rx_q);
1396 wake_up(&port_ptr->port_rx_wait_q);
1397 mutex_unlock(&port_ptr->port_rx_q_lock);
1398
1399 return pkt->length;
1400}
1401
1402static int msm_ipc_router_write_pkt(struct msm_ipc_port *src,
1403 struct msm_ipc_router_remote_port *rport_ptr,
1404 struct rr_packet *pkt)
1405{
1406 struct sk_buff *head_skb;
1407 struct rr_header *hdr;
1408 struct msm_ipc_router_xprt_info *xprt_info;
1409 struct msm_ipc_routing_table_entry *rt_entry;
1410 int ret;
1411 DEFINE_WAIT(__wait);
1412
1413 if (!rport_ptr || !src || !pkt)
1414 return -EINVAL;
1415
1416 head_skb = skb_peek(pkt->pkt_fragment_q);
1417 hdr = (struct rr_header *)skb_push(head_skb, IPC_ROUTER_HDR_SIZE);
1418 if (!hdr) {
1419 pr_err("%s: Prepend Header failed\n", __func__);
1420 return -ENOMEM;
1421 }
1422 hdr->version = IPC_ROUTER_VERSION;
1423 hdr->type = IPC_ROUTER_CTRL_CMD_DATA;
1424 hdr->src_node_id = src->this_port.node_id;
1425 hdr->src_port_id = src->this_port.port_id;
1426 hdr->size = pkt->length;
1427 hdr->confirm_rx = 0;
1428 hdr->dst_node_id = rport_ptr->node_id;
1429 hdr->dst_port_id = rport_ptr->port_id;
1430 pkt->length += IPC_ROUTER_HDR_SIZE;
1431
1432 for (;;) {
1433 prepare_to_wait(&rport_ptr->quota_wait, &__wait,
1434 TASK_INTERRUPTIBLE);
1435 mutex_lock(&rport_ptr->quota_lock);
1436 if (rport_ptr->tx_quota_cnt <
1437 IPC_ROUTER_DEFAULT_RX_QUOTA)
1438 break;
1439 if (signal_pending(current))
1440 break;
1441 mutex_unlock(&rport_ptr->quota_lock);
1442 schedule();
1443 }
1444 finish_wait(&rport_ptr->quota_wait, &__wait);
1445
1446 if (signal_pending(current)) {
1447 mutex_unlock(&rport_ptr->quota_lock);
1448 return -ERESTARTSYS;
1449 }
1450 rport_ptr->tx_quota_cnt++;
1451 if (rport_ptr->tx_quota_cnt == IPC_ROUTER_DEFAULT_RX_QUOTA)
1452 hdr->confirm_rx = 1;
1453 mutex_unlock(&rport_ptr->quota_lock);
1454
1455 mutex_lock(&routing_table_lock);
1456 rt_entry = lookup_routing_table(hdr->dst_node_id);
1457 if (!rt_entry || !rt_entry->xprt_info) {
1458 mutex_unlock(&routing_table_lock);
1459 pr_err("%s: Remote node %d not up\n",
1460 __func__, hdr->dst_node_id);
1461 return -ENODEV;
1462 }
1463 mutex_lock(&rt_entry->lock);
1464 xprt_info = rt_entry->xprt_info;
1465 mutex_lock(&xprt_info->tx_lock);
1466 ret = xprt_info->xprt->write(pkt, pkt->length, 0);
1467 mutex_unlock(&xprt_info->tx_lock);
1468 mutex_unlock(&rt_entry->lock);
1469 mutex_unlock(&routing_table_lock);
1470
1471 if (ret < 0) {
1472 pr_err("%s: Write on XPRT failed\n", __func__);
1473 return ret;
1474 }
1475
1476 RAW_HDR("[w rr_h] "
1477 "ver=%i,type=%s,src_nid=%08x,src_port_id=%08x,"
1478 "confirm_rx=%i,size=%3i,dst_pid=%08x,dst_cid=%08x\n",
1479 hdr->version, type_to_str(hdr->type),
1480 hdr->src_node_id, hdr->src_port_id,
1481 hdr->confirm_rx, hdr->size,
1482 hdr->dst_node_id, hdr->dst_port_id);
1483
1484#if defined(CONFIG_MSM_SMD_LOGGING)
1485#if defined(DEBUG)
1486 if (msm_ipc_router_debug_mask & SMEM_LOG) {
1487 smem_log_event((SMEM_LOG_PROC_ID_APPS |
1488 SMEM_LOG_RPC_ROUTER_EVENT_BASE |
1489 IPC_ROUTER_LOG_EVENT_TX),
1490 (hdr->src_node_id << 24) |
1491 (hdr->src_port_id & 0xffffff),
1492 (hdr->dst_node_id << 24) |
1493 (hdr->dst_port_id & 0xffffff),
1494 (hdr->type << 24) | (hdr->confirm_rx << 16) |
1495 (hdr->size & 0xffff));
1496 }
1497#endif
1498#endif
1499
1500 return pkt->length;
1501}
1502
1503int msm_ipc_router_send_to(struct msm_ipc_port *src,
1504 struct sk_buff_head *data,
1505 struct msm_ipc_addr *dest)
1506{
1507 uint32_t dst_node_id = 0, dst_port_id = 0;
1508 struct msm_ipc_server *server;
1509 struct msm_ipc_server_port *server_port;
1510 struct msm_ipc_router_remote_port *rport_ptr = NULL;
1511 struct rr_packet *pkt;
1512 int ret;
1513
1514 if (!src || !data || !dest) {
1515 pr_err("%s: Invalid Parameters\n", __func__);
1516 return -EINVAL;
1517 }
1518
1519 /* Resolve Address*/
1520 if (dest->addrtype == MSM_IPC_ADDR_ID) {
1521 dst_node_id = dest->addr.port_addr.node_id;
1522 dst_port_id = dest->addr.port_addr.port_id;
1523 } else if (dest->addrtype == MSM_IPC_ADDR_NAME) {
1524 server = msm_ipc_router_lookup_server(
1525 dest->addr.port_name.service,
1526 dest->addr.port_name.instance,
1527 0, 0);
1528 if (!server) {
1529 pr_err("%s: Destination not reachable\n", __func__);
1530 return -ENODEV;
1531 }
1532 mutex_lock(&server_list_lock);
1533 server_port = list_first_entry(&server->server_port_list,
1534 struct msm_ipc_server_port,
1535 list);
1536 dst_node_id = server_port->server_addr.node_id;
1537 dst_port_id = server_port->server_addr.port_id;
1538 mutex_unlock(&server_list_lock);
1539 }
1540 if (dst_node_id == IPC_ROUTER_NID_LOCAL) {
1541 ret = loopback_data(src, dst_port_id, data);
1542 return ret;
1543 }
1544
1545 /* Achieve Flow control */
1546 rport_ptr = msm_ipc_router_lookup_remote_port(dst_node_id,
1547 dst_port_id);
1548 if (!rport_ptr) {
1549 rport_ptr = msm_ipc_router_create_remote_port(dst_node_id,
1550 dst_port_id);
1551 if (!rport_ptr) {
1552 pr_err("%s: Could not create remote port\n", __func__);
1553 return -ENOMEM;
1554 }
1555 }
1556
1557 pkt = create_pkt(data);
1558 if (!pkt) {
1559 pr_err("%s: Pkt creation failed\n", __func__);
1560 return -ENOMEM;
1561 }
1562
1563 ret = msm_ipc_router_write_pkt(src, rport_ptr, pkt);
1564 release_pkt(pkt);
1565
1566 return ret;
1567}
1568
1569int msm_ipc_router_read(struct msm_ipc_port *port_ptr,
1570 struct sk_buff_head **data,
1571 size_t buf_len)
1572{
1573 struct rr_packet *pkt;
1574 int ret;
1575
1576 if (!port_ptr || !data)
1577 return -EINVAL;
1578
1579 mutex_lock(&port_ptr->port_rx_q_lock);
1580 if (list_empty(&port_ptr->port_rx_q)) {
1581 mutex_unlock(&port_ptr->port_rx_q_lock);
1582 return -EAGAIN;
1583 }
1584
1585 pkt = list_first_entry(&port_ptr->port_rx_q, struct rr_packet, list);
1586 if ((buf_len) && ((pkt->length - IPC_ROUTER_HDR_SIZE) > buf_len)) {
1587 mutex_unlock(&port_ptr->port_rx_q_lock);
1588 return -ETOOSMALL;
1589 }
1590 list_del(&pkt->list);
1591 if (list_empty(&port_ptr->port_rx_q))
1592 wake_unlock(&port_ptr->port_rx_wake_lock);
1593 *data = pkt->pkt_fragment_q;
1594 ret = pkt->length;
1595 kfree(pkt);
1596 mutex_unlock(&port_ptr->port_rx_q_lock);
1597
1598 return ret;
1599}
1600
1601int msm_ipc_router_recv_from(struct msm_ipc_port *port_ptr,
1602 struct sk_buff_head **data,
1603 struct msm_ipc_addr *src,
1604 unsigned long timeout)
1605{
1606 int ret, data_len, align_size;
1607 struct sk_buff *temp_skb;
1608 struct rr_header *hdr = NULL;
1609
1610 if (!port_ptr || !data) {
1611 pr_err("%s: Invalid pointers being passed\n", __func__);
1612 return -EINVAL;
1613 }
1614
1615 *data = NULL;
1616 mutex_lock(&port_ptr->port_rx_q_lock);
1617 while (list_empty(&port_ptr->port_rx_q)) {
1618 mutex_unlock(&port_ptr->port_rx_q_lock);
1619 if (timeout < 0) {
1620 ret = wait_event_interruptible(
1621 port_ptr->port_rx_wait_q,
1622 !list_empty(&port_ptr->port_rx_q));
1623 if (ret)
1624 return ret;
1625 } else if (timeout > 0) {
1626 timeout = wait_event_interruptible_timeout(
1627 port_ptr->port_rx_wait_q,
1628 !list_empty(&port_ptr->port_rx_q),
1629 timeout);
1630 if (timeout < 0)
1631 return -EFAULT;
1632 }
1633 if (timeout == 0)
1634 return -ETIMEDOUT;
1635 mutex_lock(&port_ptr->port_rx_q_lock);
1636 }
1637 mutex_unlock(&port_ptr->port_rx_q_lock);
1638
1639 ret = msm_ipc_router_read(port_ptr, data, 0);
1640 if (ret <= 0 || !(*data))
1641 return ret;
1642
1643 temp_skb = skb_peek(*data);
1644 hdr = (struct rr_header *)(temp_skb->data);
1645 if (src) {
1646 src->addrtype = MSM_IPC_ADDR_ID;
1647 src->addr.port_addr.node_id = hdr->src_node_id;
1648 src->addr.port_addr.port_id = hdr->src_port_id;
1649 }
1650
1651 data_len = hdr->size;
1652 skb_pull(temp_skb, IPC_ROUTER_HDR_SIZE);
1653 align_size = ALIGN_SIZE(data_len);
1654 if (align_size) {
1655 temp_skb = skb_peek_tail(*data);
1656 skb_trim(temp_skb, (temp_skb->len - align_size));
1657 }
1658 return data_len;
1659}
1660
1661struct msm_ipc_port *msm_ipc_router_create_port(
1662 void (*notify)(unsigned event, void *data, void *addr, void *priv),
1663 void *priv)
1664{
1665 struct msm_ipc_port *port_ptr;
1666
1667 port_ptr = msm_ipc_router_create_raw_port(NULL, notify, priv);
1668 if (!port_ptr)
1669 pr_err("%s: port_ptr alloc failed\n", __func__);
1670
1671 return port_ptr;
1672}
1673
1674int msm_ipc_router_close_port(struct msm_ipc_port *port_ptr)
1675{
1676 union rr_control_msg msg;
1677 struct rr_packet *pkt, *temp_pkt;
1678 struct msm_ipc_server *server;
1679
1680 if (!port_ptr)
1681 return -EINVAL;
1682
1683 if (port_ptr->type == SERVER_PORT || port_ptr->type == CLIENT_PORT) {
1684 if (port_ptr->type == SERVER_PORT) {
1685 msg.cmd = IPC_ROUTER_CTRL_CMD_REMOVE_SERVER;
1686 msg.srv.service = port_ptr->port_name.service;
1687 msg.srv.instance = port_ptr->port_name.instance;
1688 msg.srv.node_id = port_ptr->this_port.node_id;
1689 msg.srv.port_id = port_ptr->this_port.port_id;
1690 RR("x REMOVE_SERVER Name=%d:%08x Id=%d:%08x\n",
1691 msg.srv.service, msg.srv.instance,
1692 msg.srv.node_id, msg.srv.port_id);
1693 } else if (port_ptr->type == CLIENT_PORT) {
1694 msg.cmd = IPC_ROUTER_CTRL_CMD_REMOVE_CLIENT;
1695 msg.cli.node_id = port_ptr->this_port.node_id;
1696 msg.cli.port_id = port_ptr->this_port.port_id;
1697 RR("x REMOVE_CLIENT id=%d:%08x\n",
1698 msg.cli.node_id, msg.cli.port_id);
1699 }
1700 broadcast_ctl_msg(&msg);
1701 broadcast_ctl_msg_locally(&msg);
1702 }
1703
1704 mutex_lock(&port_ptr->port_rx_q_lock);
1705 list_for_each_entry_safe(pkt, temp_pkt, &port_ptr->port_rx_q, list) {
1706 list_del(&pkt->list);
1707 release_pkt(pkt);
1708 }
1709 mutex_unlock(&port_ptr->port_rx_q_lock);
1710
1711 wake_lock_destroy(&port_ptr->port_rx_wake_lock);
1712 if (port_ptr->type == SERVER_PORT) {
1713 server = msm_ipc_router_lookup_server(
1714 port_ptr->port_name.service,
1715 port_ptr->port_name.instance,
1716 port_ptr->this_port.node_id,
1717 port_ptr->this_port.port_id);
1718 if (server)
1719 msm_ipc_router_destroy_server(server,
1720 port_ptr->this_port.node_id,
1721 port_ptr->this_port.port_id);
1722 mutex_lock(&local_ports_lock);
1723 list_del(&port_ptr->list);
1724 mutex_unlock(&local_ports_lock);
1725 } else if (port_ptr->type == CLIENT_PORT) {
1726 mutex_lock(&local_ports_lock);
1727 list_del(&port_ptr->list);
1728 mutex_unlock(&local_ports_lock);
1729 } else if (port_ptr->type == CONTROL_PORT) {
1730 mutex_lock(&control_ports_lock);
1731 list_del(&port_ptr->list);
1732 mutex_unlock(&control_ports_lock);
1733 }
1734
1735 kfree(port_ptr);
1736 return 0;
1737}
1738
1739int msm_ipc_router_get_curr_pkt_size(struct msm_ipc_port *port_ptr)
1740{
1741 struct rr_packet *pkt;
1742 int rc = 0;
1743
1744 if (!port_ptr)
1745 return -EINVAL;
1746
1747 mutex_lock(&port_ptr->port_rx_q_lock);
1748 if (!list_empty(&port_ptr->port_rx_q)) {
1749 pkt = list_first_entry(&port_ptr->port_rx_q,
1750 struct rr_packet, list);
1751 rc = pkt->length;
1752 }
1753 mutex_unlock(&port_ptr->port_rx_q_lock);
1754
1755 return rc;
1756}
1757
1758int msm_ipc_router_bind_control_port(struct msm_ipc_port *port_ptr)
1759{
1760 if (!port_ptr)
1761 return -EINVAL;
1762
1763 mutex_lock(&local_ports_lock);
1764 list_del(&port_ptr->list);
1765 mutex_unlock(&local_ports_lock);
1766 port_ptr->type = CONTROL_PORT;
1767 mutex_lock(&control_ports_lock);
1768 list_add_tail(&port_ptr->list, &control_ports);
1769 mutex_unlock(&control_ports_lock);
1770
1771 return 0;
1772}
1773
1774int msm_ipc_router_lookup_server_name(struct msm_ipc_port_name *srv_name,
1775 struct msm_ipc_port_addr *srv_addr,
1776 int num_entries_in_array)
1777{
1778 struct msm_ipc_server *server;
1779 struct msm_ipc_server_port *server_port;
1780 int i = 0; /*num_entries_found*/
1781
1782 if (!srv_name) {
1783 pr_err("%s: Invalid srv_name\n", __func__);
1784 return -EINVAL;
1785 }
1786
1787 if (num_entries_in_array && !srv_addr) {
1788 pr_err("%s: srv_addr NULL\n", __func__);
1789 return -EINVAL;
1790 }
1791
1792 server = msm_ipc_router_lookup_server(srv_name->service,
1793 srv_name->instance, 0, 0);
1794 if (!server)
1795 return -ENODEV;
1796
1797 mutex_lock(&server_list_lock);
1798 list_for_each_entry(server_port, &server->server_port_list, list) {
1799 if (i < num_entries_in_array) {
1800 srv_addr[i].node_id = server_port->server_addr.node_id;
1801 srv_addr[i].port_id = server_port->server_addr.port_id;
1802 }
1803 i++;
1804 }
1805 mutex_unlock(&server_list_lock);
1806
1807 return i;
1808}
1809
1810int msm_ipc_router_close(void)
1811{
1812 struct msm_ipc_router_xprt_info *xprt_info, *tmp_xprt_info;
1813
1814 mutex_lock(&xprt_info_list_lock);
1815 list_for_each_entry_safe(xprt_info, tmp_xprt_info,
1816 &xprt_info_list, list) {
1817 xprt_info->xprt->close();
1818 list_del(&xprt_info->list);
1819 kfree(xprt_info);
1820 }
1821 mutex_unlock(&xprt_info_list_lock);
1822 return 0;
1823}
1824
1825#if defined(CONFIG_DEBUG_FS)
1826static int dump_routing_table(char *buf, int max)
1827{
1828 int i = 0, j;
1829 struct msm_ipc_routing_table_entry *rt_entry;
1830
1831 for (j = 0; j < RT_HASH_SIZE; j++) {
1832 mutex_lock(&routing_table_lock);
1833 list_for_each_entry(rt_entry, &routing_table[j], list) {
1834 mutex_lock(&rt_entry->lock);
1835 i += scnprintf(buf + i, max - i,
1836 "Node Id: 0x%08x\n", rt_entry->node_id);
1837 if (j == IPC_ROUTER_NID_LOCAL) {
1838 i += scnprintf(buf + i, max - i,
1839 "XPRT Name: Loopback\n");
1840 i += scnprintf(buf + i, max - i,
1841 "Next Hop: %d\n", rt_entry->node_id);
1842 } else {
1843 i += scnprintf(buf + i, max - i,
1844 "XPRT Name: %s\n",
1845 rt_entry->xprt_info->xprt->name);
1846 i += scnprintf(buf + i, max - i,
1847 "Next Hop: 0x%08x\n",
1848 rt_entry->xprt_info->remote_node_id);
1849 }
1850 i += scnprintf(buf + i, max - i, "\n");
1851 mutex_unlock(&rt_entry->lock);
1852 }
1853 mutex_unlock(&routing_table_lock);
1854 }
1855
1856 return i;
1857}
1858
1859static int dump_xprt_info(char *buf, int max)
1860{
1861 int i = 0;
1862 struct msm_ipc_router_xprt_info *xprt_info;
1863
1864 mutex_lock(&xprt_info_list_lock);
1865 list_for_each_entry(xprt_info, &xprt_info_list, list) {
1866 i += scnprintf(buf + i, max - i, "XPRT Name: %s\n",
1867 xprt_info->xprt->name);
1868 i += scnprintf(buf + i, max - i, "Link Id: %d\n",
1869 xprt_info->xprt->link_id);
1870 i += scnprintf(buf + i, max - i, "Initialized: %s\n",
1871 (xprt_info->initialized ? "Y" : "N"));
1872 i += scnprintf(buf + i, max - i, "Remote Node Id: 0x%08x\n",
1873 xprt_info->remote_node_id);
1874 i += scnprintf(buf + i, max - i, "\n");
1875 }
1876 mutex_unlock(&xprt_info_list_lock);
1877
1878 return i;
1879}
1880
1881static int dump_servers(char *buf, int max)
1882{
1883 int i = 0, j;
1884 struct msm_ipc_server *server;
1885 struct msm_ipc_server_port *server_port;
1886
1887 mutex_lock(&server_list_lock);
1888 for (j = 0; j < SRV_HASH_SIZE; j++) {
1889 list_for_each_entry(server, &server_list[j], list) {
1890 list_for_each_entry(server_port,
1891 &server->server_port_list,
1892 list) {
1893 i += scnprintf(buf + i, max - i, "Service: "
1894 "0x%08x\n", server->name.service);
1895 i += scnprintf(buf + i, max - i, "Instance: "
1896 "0x%08x\n", server->name.instance);
1897 i += scnprintf(buf + i, max - i,
1898 "Node_id: 0x%08x\n",
1899 server_port->server_addr.node_id);
1900 i += scnprintf(buf + i, max - i,
1901 "Port_id: 0x%08x\n",
1902 server_port->server_addr.port_id);
1903 i += scnprintf(buf + i, max - i, "\n");
1904 }
1905 }
1906 }
1907 mutex_unlock(&server_list_lock);
1908
1909 return i;
1910}
1911
1912static int dump_remote_ports(char *buf, int max)
1913{
1914 int i = 0, j, k;
1915 struct msm_ipc_router_remote_port *rport_ptr;
1916 struct msm_ipc_routing_table_entry *rt_entry;
1917
1918 for (j = 0; j < RT_HASH_SIZE; j++) {
1919 mutex_lock(&routing_table_lock);
1920 list_for_each_entry(rt_entry, &routing_table[j], list) {
1921 mutex_lock(&rt_entry->lock);
1922 for (k = 0; k < RP_HASH_SIZE; k++) {
1923 list_for_each_entry(rport_ptr,
1924 &rt_entry->remote_port_list[k],
1925 list) {
1926 i += scnprintf(buf + i, max - i,
1927 "Node_id: 0x%08x\n",
1928 rport_ptr->node_id);
1929 i += scnprintf(buf + i, max - i,
1930 "Port_id: 0x%08x\n",
1931 rport_ptr->port_id);
1932 i += scnprintf(buf + i, max - i,
1933 "Quota_cnt: %d\n",
1934 rport_ptr->tx_quota_cnt);
1935 i += scnprintf(buf + i, max - i, "\n");
1936 }
1937 }
1938 mutex_unlock(&rt_entry->lock);
1939 }
1940 mutex_unlock(&routing_table_lock);
1941 }
1942
1943 return i;
1944}
1945
1946static int dump_control_ports(char *buf, int max)
1947{
1948 int i = 0;
1949 struct msm_ipc_port *port_ptr;
1950
1951 mutex_lock(&control_ports_lock);
1952 list_for_each_entry(port_ptr, &control_ports, list) {
1953 i += scnprintf(buf + i, max - i, "Node_id: 0x%08x\n",
1954 port_ptr->this_port.node_id);
1955 i += scnprintf(buf + i, max - i, "Port_id: 0x%08x\n",
1956 port_ptr->this_port.port_id);
1957 i += scnprintf(buf + i, max - i, "\n");
1958 }
1959 mutex_unlock(&control_ports_lock);
1960
1961 return i;
1962}
1963
1964static int dump_local_ports(char *buf, int max)
1965{
1966 int i = 0, j;
1967 unsigned long flags;
1968 struct msm_ipc_port *port_ptr;
1969
1970 mutex_lock(&local_ports_lock);
1971 for (j = 0; j < LP_HASH_SIZE; j++) {
1972 list_for_each_entry(port_ptr, &local_ports[j], list) {
1973 spin_lock_irqsave(&port_ptr->port_lock, flags);
1974 i += scnprintf(buf + i, max - i, "Node_id: 0x%08x\n",
1975 port_ptr->this_port.node_id);
1976 i += scnprintf(buf + i, max - i, "Port_id: 0x%08x\n",
1977 port_ptr->this_port.port_id);
1978 i += scnprintf(buf + i, max - i, "# pkts tx'd %d\n",
1979 port_ptr->num_tx);
1980 i += scnprintf(buf + i, max - i, "# pkts rx'd %d\n",
1981 port_ptr->num_rx);
1982 i += scnprintf(buf + i, max - i, "# bytes tx'd %ld\n",
1983 port_ptr->num_tx_bytes);
1984 i += scnprintf(buf + i, max - i, "# bytes rx'd %ld\n",
1985 port_ptr->num_rx_bytes);
1986 spin_unlock_irqrestore(&port_ptr->port_lock, flags);
1987 i += scnprintf(buf + i, max - i, "\n");
1988 }
1989 }
1990 mutex_unlock(&local_ports_lock);
1991
1992 return i;
1993}
1994
1995#define DEBUG_BUFMAX 4096
1996static char debug_buffer[DEBUG_BUFMAX];
1997
1998static ssize_t debug_read(struct file *file, char __user *buf,
1999 size_t count, loff_t *ppos)
2000{
2001 int (*fill)(char *buf, int max) = file->private_data;
2002 int bsize = fill(debug_buffer, DEBUG_BUFMAX);
2003 return simple_read_from_buffer(buf, count, ppos, debug_buffer, bsize);
2004}
2005
2006static int debug_open(struct inode *inode, struct file *file)
2007{
2008 file->private_data = inode->i_private;
2009 return 0;
2010}
2011
2012static const struct file_operations debug_ops = {
2013 .read = debug_read,
2014 .open = debug_open,
2015};
2016
2017static void debug_create(const char *name, mode_t mode,
2018 struct dentry *dent,
2019 int (*fill)(char *buf, int max))
2020{
2021 debugfs_create_file(name, mode, dent, fill, &debug_ops);
2022}
2023
2024static void debugfs_init(void)
2025{
2026 struct dentry *dent;
2027
2028 dent = debugfs_create_dir("msm_ipc_router", 0);
2029 if (IS_ERR(dent))
2030 return;
2031
2032 debug_create("dump_local_ports", 0444, dent,
2033 dump_local_ports);
2034 debug_create("dump_remote_ports", 0444, dent,
2035 dump_remote_ports);
2036 debug_create("dump_control_ports", 0444, dent,
2037 dump_control_ports);
2038 debug_create("dump_servers", 0444, dent,
2039 dump_servers);
2040 debug_create("dump_xprt_info", 0444, dent,
2041 dump_xprt_info);
2042 debug_create("dump_routing_table", 0444, dent,
2043 dump_routing_table);
2044}
2045
2046#else
2047static void debugfs_init(void) {}
2048#endif
2049
2050static int msm_ipc_router_add_xprt(struct msm_ipc_router_xprt *xprt)
2051{
2052 struct msm_ipc_router_xprt_info *xprt_info;
2053 struct msm_ipc_routing_table_entry *rt_entry;
2054
2055 xprt_info = kmalloc(sizeof(struct msm_ipc_router_xprt_info),
2056 GFP_KERNEL);
2057 if (!xprt_info)
2058 return -ENOMEM;
2059
2060 xprt_info->xprt = xprt;
2061 xprt_info->initialized = 0;
2062 xprt_info->remote_node_id = -1;
2063 INIT_LIST_HEAD(&xprt_info->pkt_list);
2064 init_waitqueue_head(&xprt_info->read_wait);
2065 mutex_init(&xprt_info->rx_lock);
2066 mutex_init(&xprt_info->tx_lock);
2067 wake_lock_init(&xprt_info->wakelock,
2068 WAKE_LOCK_SUSPEND, xprt->name);
2069 xprt_info->need_len = 0;
2070 INIT_WORK(&xprt_info->read_data, do_read_data);
2071 INIT_LIST_HEAD(&xprt_info->list);
2072
2073 xprt_info->workqueue = create_singlethread_workqueue(xprt->name);
2074 if (!xprt_info->workqueue) {
2075 kfree(xprt_info);
2076 return -ENOMEM;
2077 }
2078
2079 if (!strcmp(xprt->name, "msm_ipc_router_loopback_xprt")) {
2080 xprt_info->remote_node_id = IPC_ROUTER_NID_LOCAL;
2081 xprt_info->initialized = 1;
2082 }
2083
2084 mutex_lock(&xprt_info_list_lock);
2085 list_add_tail(&xprt_info->list, &xprt_info_list);
2086 mutex_unlock(&xprt_info_list_lock);
2087
2088 mutex_lock(&routing_table_lock);
2089 if (!routing_table_inited) {
2090 init_routing_table();
2091 rt_entry = alloc_routing_table_entry(IPC_ROUTER_NID_LOCAL);
2092 add_routing_table_entry(rt_entry);
2093 routing_table_inited = 1;
2094 }
2095 mutex_unlock(&routing_table_lock);
2096
2097 queue_work(xprt_info->workqueue, &xprt_info->read_data);
2098
2099 xprt->priv = xprt_info;
2100
2101 return 0;
2102}
2103
2104
2105void msm_ipc_router_xprt_notify(struct msm_ipc_router_xprt *xprt,
2106 unsigned event,
2107 void *data)
2108{
2109 struct msm_ipc_router_xprt_info *xprt_info = xprt->priv;
2110 struct rr_packet *pkt;
2111
2112 if (event == IPC_ROUTER_XPRT_EVENT_OPEN) {
2113 msm_ipc_router_add_xprt(xprt);
2114 return;
2115 }
2116
2117 if (!data)
2118 return;
2119
2120 while (!xprt_info) {
2121 msleep(100);
2122 xprt_info = xprt->priv;
2123 }
2124
2125 pkt = clone_pkt((struct rr_packet *)data);
2126 if (!pkt)
2127 return;
2128
2129 mutex_lock(&xprt_info->rx_lock);
2130 list_add_tail(&pkt->list, &xprt_info->pkt_list);
2131 wake_lock(&xprt_info->wakelock);
2132 wake_up(&xprt_info->read_wait);
2133 mutex_unlock(&xprt_info->rx_lock);
2134}
2135
2136static int __init msm_ipc_router_init(void)
2137{
2138 int i, ret;
2139 struct msm_ipc_routing_table_entry *rt_entry;
2140
2141 msm_ipc_router_debug_mask |= SMEM_LOG;
2142 debugfs_init();
2143
2144 for (i = 0; i < SRV_HASH_SIZE; i++)
2145 INIT_LIST_HEAD(&server_list[i]);
2146
2147 for (i = 0; i < LP_HASH_SIZE; i++)
2148 INIT_LIST_HEAD(&local_ports[i]);
2149
2150 mutex_lock(&routing_table_lock);
2151 if (!routing_table_inited) {
2152 init_routing_table();
2153 rt_entry = alloc_routing_table_entry(IPC_ROUTER_NID_LOCAL);
2154 add_routing_table_entry(rt_entry);
2155 routing_table_inited = 1;
2156 }
2157 mutex_unlock(&routing_table_lock);
2158
2159 init_waitqueue_head(&newserver_wait);
2160 ret = msm_ipc_router_init_sockets();
2161 if (ret < 0)
2162 pr_err("%s: Init sockets failed\n", __func__);
2163
2164 return ret;
2165}
2166
2167module_init(msm_ipc_router_init);
2168MODULE_DESCRIPTION("MSM IPC Router");
2169MODULE_LICENSE("GPL v2");