diff options
| author | Amir Levy <alevy@codeaurora.org> | 2016-04-06 17:53:00 +0300 |
|---|---|---|
| committer | Jeevan Shriram <jshriram@codeaurora.org> | 2016-04-07 15:59:22 -0700 |
| commit | 40fa808ef493cb5e1986498de14be96117d9a42d (patch) | |
| tree | fe5396d46d691ebcdc09b67937dc4dc106769734 /drivers/platform | |
| parent | 6f398060896f29f7ee202d4cb6b126bac29f66e2 (diff) | |
msm: ipa3: add ipc logging for odu_bridge driver
Add ipc logging ability to odu_bridge driver. Messages will be directed
to ipc logging buffer which can be found in crashdump.
CRs-fixed: 999935
Change-Id: Iadfcf4a88472c54fbfe066fa6304146140b76201
Signed-off-by: Amir Levy <alevy@codeaurora.org>
Diffstat (limited to 'drivers/platform')
| -rw-r--r-- | drivers/platform/msm/ipa/ipa_clients/odu_bridge.c | 130 |
1 files changed, 116 insertions, 14 deletions
diff --git a/drivers/platform/msm/ipa/ipa_clients/odu_bridge.c b/drivers/platform/msm/ipa/ipa_clients/odu_bridge.c index a4ec67da1165..c388925f4679 100644 --- a/drivers/platform/msm/ipa/ipa_clients/odu_bridge.c +++ b/drivers/platform/msm/ipa/ipa_clients/odu_bridge.c @@ -23,21 +23,55 @@ #include <linux/types.h> #include <linux/ipv6.h> #include <net/addrconf.h> +#include <linux/ipc_logging.h> #include <linux/ipa.h> #include <linux/cdev.h> #include <linux/ipa_odu_bridge.h> #define ODU_BRIDGE_DRV_NAME "odu_ipa_bridge" +#define ODU_IPC_LOG_PAGES 10 +#define ODU_IPC_LOG(buf, fmt, args...) \ + ipc_log_string((buf), \ + ODU_BRIDGE_DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args) + #define ODU_BRIDGE_DBG(fmt, args...) \ - pr_debug(ODU_BRIDGE_DRV_NAME " %s:%d " fmt, \ - __func__, __LINE__, ## args) + do { \ + pr_debug(ODU_BRIDGE_DRV_NAME " %s:%d " fmt, \ + __func__, __LINE__, ## args); \ + if (odu_bridge_ctx) { \ + ODU_IPC_LOG(odu_bridge_ctx->logbuf, \ + fmt, ## args); \ + ODU_IPC_LOG(odu_bridge_ctx->logbuf_low, \ + fmt, ## args); \ + } \ + } while (0) +#define ODU_BRIDGE_DBG_LOW(fmt, args...) \ + do { \ + pr_debug(ODU_BRIDGE_DRV_NAME " %s:%d " fmt, \ + __func__, __LINE__, ## args); \ + if (odu_bridge_ctx && \ + odu_bridge_ctx->enable_low_prio_print) { \ + ODU_IPC_LOG(odu_bridge_ctx->logbuf_low, \ + fmt, ## args); \ + } \ + } while (0) #define ODU_BRIDGE_ERR(fmt, args...) \ - pr_err(ODU_BRIDGE_DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args) + do { \ + pr_err(ODU_BRIDGE_DRV_NAME " %s:%d " fmt, \ + __func__, __LINE__, ## args); \ + if (odu_bridge_ctx) { \ + ODU_IPC_LOG(odu_bridge_ctx->logbuf, \ + fmt, ## args); \ + ODU_IPC_LOG(odu_bridge_ctx->logbuf_low, \ + fmt, ## args); \ + } \ + } while (0) + #define ODU_BRIDGE_FUNC_ENTRY() \ - ODU_BRIDGE_DBG("ENTRY\n") + ODU_BRIDGE_DBG_LOW("ENTRY\n") #define ODU_BRIDGE_FUNC_EXIT() \ - ODU_BRIDGE_DBG("EXIT\n") + ODU_BRIDGE_DBG_LOW("EXIT\n") #define ODU_BRIDGE_IS_QMI_ADDR(daddr) \ @@ -55,6 +89,17 @@ compat_uptr_t) #endif +#define IPA_ODU_VER_CHECK() \ + do { \ + ret = 0;\ + if (ipa_get_hw_type() == IPA_HW_None) { \ + pr_err("IPA HW is unknown\n"); \ + ret = -EFAULT; \ + } \ + else if (ipa_get_hw_type() < IPA_HW_v3_0) \ + ret = 1; \ + } while (0) + /** * struct stats - driver statistics, viewable using debugfs * @num_ul_packets: number of packets bridged in uplink direction @@ -111,6 +156,9 @@ struct odu_bridge_ctx { u32 odu_emb_cons_hdl; u32 odu_teth_cons_hdl; u32 ipa_sys_desc_size; + void *logbuf; + void *logbuf_low; + u32 enable_low_prio_print; }; static struct odu_bridge_ctx *odu_bridge_ctx; @@ -150,7 +198,7 @@ static void odu_bridge_teth_cons_cb(void *priv, enum ipa_dp_evt_type evt, ipv6hdr = (struct ipv6hdr *)(skb->data + ETH_HLEN); if (ipv6hdr->version == 6 && ipv6_addr_is_multicast(&ipv6hdr->daddr)) { - ODU_BRIDGE_DBG("Multicast pkt, send to APPS and adapter\n"); + ODU_BRIDGE_DBG_LOW("Multicast pkt, send to APPS and adapter\n"); skb_copied = skb_clone(skb, GFP_KERNEL); if (skb_copied) { odu_bridge_ctx->tx_dp_notify(odu_bridge_ctx->priv, @@ -235,7 +283,7 @@ static int odu_bridge_connect_bridge(void) memset(&odu_emb_cons_params, 0, sizeof(odu_emb_cons_params)); /* Build IPA Resource manager dependency graph */ - ODU_BRIDGE_DBG("build dependency graph\n"); + ODU_BRIDGE_DBG_LOW("build dependency graph\n"); res = ipa_rm_add_dependency(IPA_RM_RESOURCE_ODU_ADAPT_PROD, IPA_RM_RESOURCE_Q6_CONS); if (res && res != -EINPROGRESS) { @@ -294,9 +342,9 @@ static int odu_bridge_connect_bridge(void) goto fail_odu_emb_cons; } - ODU_BRIDGE_DBG("odu_prod_hdl = %d, odu_emb_cons_hdl = %d\n", + ODU_BRIDGE_DBG_LOW("odu_prod_hdl = %d, odu_emb_cons_hdl = %d\n", odu_bridge_ctx->odu_prod_hdl, odu_bridge_ctx->odu_emb_cons_hdl); - ODU_BRIDGE_DBG("odu_teth_cons_hdl = %d\n", + ODU_BRIDGE_DBG_LOW("odu_teth_cons_hdl = %d\n", odu_bridge_ctx->odu_teth_cons_hdl); ODU_BRIDGE_FUNC_EXIT(); @@ -489,11 +537,11 @@ static int odu_bridge_set_mode(enum odu_bridge_mode mode) return -EFAULT; } - ODU_BRIDGE_DBG("setting mode: %d\n", mode); + ODU_BRIDGE_DBG_LOW("setting mode: %d\n", mode); mutex_lock(&odu_bridge_ctx->lock); if (odu_bridge_ctx->mode == mode) { - ODU_BRIDGE_DBG("same mode\n"); + ODU_BRIDGE_DBG_LOW("same mode\n"); res = 0; goto bail; } @@ -556,7 +604,7 @@ static int odu_bridge_set_llv6_addr(struct in6_addr *llv6_addr) memcpy(&odu_bridge_ctx->llv6_addr, &llv6_addr_host, sizeof(odu_bridge_ctx->llv6_addr)); - ODU_BRIDGE_DBG("LLV6 addr: %pI6c\n", &odu_bridge_ctx->llv6_addr); + ODU_BRIDGE_DBG_LOW("LLV6 addr: %pI6c\n", &odu_bridge_ctx->llv6_addr); ODU_BRIDGE_FUNC_EXIT(); @@ -635,6 +683,7 @@ static long compat_odu_bridge_ioctl(struct file *file, static struct dentry *dent; static struct dentry *dfile_stats; static struct dentry *dfile_mode; +static struct dentry *dfile_low_prio; static ssize_t odu_debugfs_stats(struct file *file, char __user *ubuf, @@ -757,6 +806,14 @@ static void odu_debugfs_init(void) goto fail; } + dfile_low_prio = debugfs_create_u32("enable_low_prio_print", + read_write_mode, + dent, &odu_bridge_ctx->enable_low_prio_print); + if (!dfile_low_prio) { + ODU_BRIDGE_ERR("could not create enable_low_prio_print file\n"); + goto fail; + } + return; fail: debugfs_remove_recursive(dent); @@ -819,7 +876,7 @@ int odu_bridge_tx_dp(struct sk_buff *skb, struct ipa_tx_meta *metadata) ipv6hdr = (struct ipv6hdr *)(skb->data + ETH_HLEN); if (ipv6hdr->version == 6 && ODU_BRIDGE_IS_QMI_ADDR(ipv6hdr->daddr)) { - ODU_BRIDGE_DBG("QMI packet\n"); + ODU_BRIDGE_DBG_LOW("QMI packet\n"); skb_copied = skb_clone(skb, GFP_KERNEL); if (!skb_copied) { ODU_BRIDGE_ERR("No memory\n"); @@ -839,7 +896,8 @@ int odu_bridge_tx_dp(struct sk_buff *skb, struct ipa_tx_meta *metadata) if (ipv6hdr->version == 6 && ipv6_addr_is_multicast(&ipv6hdr->daddr)) { - ODU_BRIDGE_DBG("Multicast pkt, send to APPS and IPA\n"); + ODU_BRIDGE_DBG_LOW( + "Multicast pkt, send to APPS and IPA\n"); skb_copied = skb_clone(skb, GFP_KERNEL); if (!skb_copied) { ODU_BRIDGE_ERR("No memory\n"); @@ -1046,6 +1104,34 @@ static void odu_bridge_deregister_properties(void) ODU_BRIDGE_FUNC_EXIT(); } +static int odu_bridge_ipc_logging_init(void) +{ + int result; + + odu_bridge_ctx->logbuf = ipc_log_context_create(ODU_IPC_LOG_PAGES, + "ipa_odu_bridge", 0); + if (odu_bridge_ctx->logbuf == NULL) { + /* we can't use odu_bridge print macros on failures */ + pr_err("odu_bridge: failed to get logbuf\n"); + return -ENOMEM; + } + + odu_bridge_ctx->logbuf_low = + ipc_log_context_create(ODU_IPC_LOG_PAGES, + "ipa_odu_bridge_low", 0); + if (odu_bridge_ctx->logbuf_low == NULL) { + pr_err("odu_bridge: failed to get logbuf_low\n"); + result = -ENOMEM; + goto fail_logbuf_low; + } + + return 0; + +fail_logbuf_low: + ipc_log_context_destroy(odu_bridge_ctx->logbuf); + return result; +} + /** * odu_bridge_init() - Initialize the ODU bridge driver * @params: initialization parameters @@ -1084,6 +1170,10 @@ int odu_bridge_init(struct odu_bridge_params *params) ODU_BRIDGE_ERR("Already initialized\n"); return -EFAULT; } + if (!ipa_is_ready()) { + ODU_BRIDGE_ERR("IPA is not ready\n"); + return -EFAULT; + } ODU_BRIDGE_DBG("device_ethaddr=%pM\n", params->device_ethaddr); @@ -1093,6 +1183,13 @@ int odu_bridge_init(struct odu_bridge_params *params) return -ENOMEM; } + res = odu_bridge_ipc_logging_init(); + if (res) { + /* ODU_BRIDGE_ERR will crash on NULL if we use it here*/ + pr_err("odu_bridge: failed to initialize ipc logging\n"); + res = -EFAULT; + goto fail_ipc_create; + } odu_bridge_ctx->class = class_create(THIS_MODULE, ODU_BRIDGE_DRV_NAME); if (!odu_bridge_ctx->class) { ODU_BRIDGE_ERR("Class_create err.\n"); @@ -1167,6 +1264,9 @@ fail_device_create: fail_alloc_chrdev_region: class_destroy(odu_bridge_ctx->class); fail_class_create: + ipc_log_context_destroy(odu_bridge_ctx->logbuf); + ipc_log_context_destroy(odu_bridge_ctx->logbuf_low); +fail_ipc_create: kfree(odu_bridge_ctx); odu_bridge_ctx = NULL; return res; @@ -1201,6 +1301,8 @@ int odu_bridge_cleanup(void) device_destroy(odu_bridge_ctx->class, odu_bridge_ctx->dev_num); unregister_chrdev_region(odu_bridge_ctx->dev_num, 1); class_destroy(odu_bridge_ctx->class); + ipc_log_context_destroy(odu_bridge_ctx->logbuf); + ipc_log_context_destroy(odu_bridge_ctx->logbuf_low); kfree(odu_bridge_ctx); odu_bridge_ctx = NULL; |
