diff options
Diffstat (limited to 'drivers/rmnet/shs/rmnet_shs_config.c')
-rw-r--r-- | drivers/rmnet/shs/rmnet_shs_config.c | 154 |
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; |