summaryrefslogtreecommitdiff
path: root/drivers/rmnet/shs/rmnet_shs_config.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rmnet/shs/rmnet_shs_config.c')
-rw-r--r--drivers/rmnet/shs/rmnet_shs_config.c154
1 files changed, 89 insertions, 65 deletions
diff --git a/drivers/rmnet/shs/rmnet_shs_config.c b/drivers/rmnet/shs/rmnet_shs_config.c
index 1bb731f..e6b4002 100644
--- a/drivers/rmnet/shs/rmnet_shs_config.c
+++ b/drivers/rmnet/shs/rmnet_shs_config.c
@@ -16,9 +16,11 @@
#include <linux/netdevice.h>
#include <linux/module.h>
#include <../drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h>
+#include <../drivers/net/ethernet/qualcomm/rmnet/rmnet_private.h>
#include "rmnet_shs_config.h"
#include "rmnet_shs.h"
#include "rmnet_shs_wq.h"
+#include "rmnet_shs_wq_genl.h"
MODULE_LICENSE("GPL v2");
@@ -31,7 +33,7 @@ unsigned int rmnet_shs_stats_enabled __read_mostly = 1;
module_param(rmnet_shs_stats_enabled, uint, 0644);
MODULE_PARM_DESC(rmnet_shs_stats_enabled, "Enable Disable stats collection");
-unsigned long int rmnet_shs_crit_err[RMNET_SHS_CRIT_ERR_MAX];
+unsigned long rmnet_shs_crit_err[RMNET_SHS_CRIT_ERR_MAX];
module_param_array(rmnet_shs_crit_err, ulong, 0, 0444);
MODULE_PARM_DESC(rmnet_shs_crit_err, "rmnet shs crtical error type");
@@ -40,43 +42,34 @@ static int rmnet_shs_dev_notify_cb(struct notifier_block *nb,
static struct notifier_block rmnet_shs_dev_notifier __read_mostly = {
.notifier_call = rmnet_shs_dev_notify_cb,
+ .priority = 2,
};
-static int rmnet_shs_dev_notify_cb(struct notifier_block *nb,
- unsigned long event, void *data);
-
static int rmnet_vnd_total;
/* Enable smart hashing capability upon call to initialize module*/
int __init rmnet_shs_module_init(void)
{
-
- if (unlikely(rmnet_shs_debug))
- pr_info("%s(): Initializing rmnet SHS module\n", __func__);
-
- if (!rmnet_shs_skb_entry)
- RCU_INIT_POINTER(rmnet_shs_skb_entry, rmnet_shs_assign);
-
+ pr_info("%s(): Starting rmnet SHS module\n", __func__);
trace_rmnet_shs_high(RMNET_SHS_MODULE, RMNET_SHS_MODULE_INIT,
0xDEF, 0xDEF, 0xDEF, 0xDEF, NULL, NULL);
+
+ if (rmnet_shs_wq_genl_init()) {
+ rm_err("%s", "SHS_GNL: Failed to init generic netlink");
+ }
+
return register_netdevice_notifier(&rmnet_shs_dev_notifier);
}
/* Remove smart hashing capability upon call to initialize module */
void __exit rmnet_shs_module_exit(void)
{
- RCU_INIT_POINTER(rmnet_shs_skb_entry, NULL);
-
- if (rmnet_shs_cfg.rmnet_shs_init_complete) {
- rmnet_shs_cancel_table();
- rmnet_shs_rx_wq_exit();
- rmnet_shs_wq_exit();
- rmnet_shs_exit();
- }
- unregister_netdevice_notifier(&rmnet_shs_dev_notifier);
- if (unlikely(rmnet_shs_debug))
- pr_info("Exiting rmnet_shs module");
trace_rmnet_shs_high(RMNET_SHS_MODULE, RMNET_SHS_MODULE_EXIT,
0xDEF, 0xDEF, 0xDEF, 0xDEF, NULL, NULL);
+ unregister_netdevice_notifier(&rmnet_shs_dev_notifier);
+
+ rmnet_shs_wq_genl_deinit();
+
+ pr_info("%s(): Exiting rmnet SHS module\n", __func__);
}
static int rmnet_shs_dev_notify_cb(struct notifier_block *nb,
@@ -84,28 +77,32 @@ static int rmnet_shs_dev_notify_cb(struct notifier_block *nb,
{
struct net_device *dev = netdev_notifier_info_to_dev(data);
- static struct net_device *phy_dev;
+ struct rmnet_priv *priv;
+ struct rmnet_port *port;
+ int ret = 0;
if (!dev) {
rmnet_shs_crit_err[RMNET_SHS_NETDEV_ERR]++;
return NOTIFY_DONE;
}
+ if (!(strncmp(dev->name, "rmnet_data", 10) == 0 ||
+ strncmp(dev->name, "r_rmnet_data", 12) == 0))
+ return NOTIFY_DONE;
+
switch (event) {
- case NETDEV_GOING_DOWN:
+ case NETDEV_UNREGISTER:
rmnet_shs_wq_reset_ep_active(dev);
-
- if (strncmp(dev->name, "rmnet_data", 10) == 0)
- rmnet_vnd_total--;
+ rmnet_vnd_total--;
/* Deinitialize if last vnd is going down or if
* phy_dev is going down.
*/
- if ((rmnet_is_real_dev_registered(dev) &&
- (!strcmp(dev->name, "rmnet_ipa0") ||
- !strcmp(dev->name, "rmnet_mhi0"))) &&
- rmnet_shs_cfg.rmnet_shs_init_complete) {
+ if (!rmnet_vnd_total && rmnet_shs_cfg.rmnet_shs_init_complete) {
+ pr_info("rmnet_shs deinit %s going down ", dev->name);
RCU_INIT_POINTER(rmnet_shs_skb_entry, NULL);
+ qmi_rmnet_ps_ind_deregister(rmnet_shs_cfg.port,
+ &rmnet_shs_cfg.rmnet_idl_ind_cb);
rmnet_shs_cancel_table();
rmnet_shs_rx_wq_exit();
rmnet_shs_wq_exit();
@@ -117,47 +114,74 @@ static int rmnet_shs_dev_notify_cb(struct notifier_block *nb,
}
break;
- case NETDEV_UP:
- if (strncmp(dev->name, "rmnet_ipa0", 10) == 0 ||
- strncmp(dev->name, "rmnet_mhi0", 10) == 0)
- phy_dev = dev;
+ case NETDEV_REGISTER:
+ rmnet_vnd_total++;
+ if (rmnet_vnd_total && !rmnet_shs_cfg.rmnet_shs_init_complete) {
+ pr_info("rmnet_shs initializing %s", dev->name);
+ priv = netdev_priv(dev);
+ port = rmnet_get_port(priv->real_dev);
+ if (!port) {
+ pr_err("rmnet_shs: invalid rmnet_port");
+ break;
+ }
+ rmnet_shs_init(priv->real_dev, dev);
+ rmnet_shs_wq_init(priv->real_dev);
+ rmnet_shs_rx_wq_init();
- if (strncmp(dev->name, "rmnet_data", 10) == 0){
- rmnet_vnd_total++;
+ rmnet_shs_cfg.is_timer_init = 1;
}
+ rmnet_shs_wq_set_ep_active(dev);
- if (strncmp(dev->name, "rmnet_data", 10) == 0) {
- /* Need separate if check to avoid
- * NULL dereferencing
- */
-
- if (phy_dev && !rmnet_shs_cfg.rmnet_shs_init_complete) {
- rmnet_shs_init(phy_dev, dev);
- rmnet_shs_wq_init(phy_dev);
- rmnet_shs_rx_wq_init();
- rmnet_shs_cfg.is_timer_init = 1;
- rmnet_shs_cfg.dl_mrk_ind_cb.priority =
- RMNET_SHS;
- rmnet_shs_cfg.dl_mrk_ind_cb.dl_hdr_handler =
- &rmnet_shs_dl_hdr_handler;
- rmnet_shs_cfg.dl_mrk_ind_cb.dl_trl_handler =
- &rmnet_shs_dl_trl_handler;
- trace_rmnet_shs_high(RMNET_SHS_MODULE,
- RMNET_SHS_MODULE_INIT_WQ,
- 0xDEF, 0xDEF, 0xDEF,
- 0xDEF, NULL, NULL);
- rmnet_shs_cfg.rmnet_idl_ind_cb.ps_on_handler =
- &rmnet_shs_ps_on_hdlr;
- rmnet_shs_cfg.rmnet_idl_ind_cb.ps_off_handler =
- &rmnet_shs_ps_off_hdlr;
- RCU_INIT_POINTER(rmnet_shs_skb_entry,
- rmnet_shs_assign);
-
+ break;
+ case NETDEV_UP:
+ if (!rmnet_shs_cfg.is_reg_dl_mrk_ind &&
+ rmnet_shs_cfg.rmnet_shs_init_complete) {
+ port = rmnet_shs_cfg.port;
+ if (!port) {
+ pr_err("rmnet_shs: invalid rmnet_cfg_port");
+ break;
}
- rmnet_shs_wq_set_ep_active(dev);
+ rmnet_shs_cfg.dl_mrk_ind_cb.priority =
+ RMNET_SHS;
+ if (port->data_format & RMNET_INGRESS_FORMAT_DL_MARKER_V2) {
+ rmnet_shs_cfg.dl_mrk_ind_cb.dl_hdr_handler_v2 =
+ &rmnet_shs_dl_hdr_handler_v2;
+ rmnet_shs_cfg.dl_mrk_ind_cb.dl_trl_handler_v2 =
+ &rmnet_shs_dl_trl_handler_v2;
+ } else {
+ rmnet_shs_cfg.dl_mrk_ind_cb.dl_hdr_handler =
+ &rmnet_shs_dl_hdr_handler;
+ rmnet_shs_cfg.dl_mrk_ind_cb.dl_trl_handler =
+ &rmnet_shs_dl_trl_handler;
+ }
+ rmnet_shs_cfg.rmnet_idl_ind_cb.ps_on_handler =
+ &rmnet_shs_ps_on_hdlr;
+ rmnet_shs_cfg.rmnet_idl_ind_cb.ps_off_handler =
+ &rmnet_shs_ps_off_hdlr;
+
+ ret = rmnet_map_dl_ind_register(port,
+ &rmnet_shs_cfg.dl_mrk_ind_cb);
+ if (ret)
+ pr_err("%s(): rmnet dl_ind registration fail\n",
+ __func__);
+
+ ret = qmi_rmnet_ps_ind_register(port,
+ &rmnet_shs_cfg.rmnet_idl_ind_cb);
+ if (ret)
+ pr_err("%s(): rmnet ps_ind registration fail\n",
+ __func__);
+ rmnet_shs_update_cfg_mask();
+ rmnet_shs_wq_refresh_new_flow_list();
+ rmnet_shs_cfg.is_reg_dl_mrk_ind = 1;
+ trace_rmnet_shs_high(RMNET_SHS_MODULE,
+ RMNET_SHS_MODULE_INIT_WQ,
+ 0xDEF, 0xDEF, 0xDEF,
+ 0xDEF, NULL, NULL);
+ RCU_INIT_POINTER(rmnet_shs_skb_entry,
+ rmnet_shs_assign);
}
break;