aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-drv.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-drv.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.c132
1 files changed, 114 insertions, 18 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
index 35a9d65664e9..48d6d44c16d0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
@@ -101,6 +101,10 @@ MODULE_VERSION(DRV_VERSION);
101MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); 101MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
102MODULE_LICENSE("GPL"); 102MODULE_LICENSE("GPL");
103 103
104#ifdef CONFIG_IWLWIFI_DEBUGFS
105static struct dentry *iwl_dbgfs_root;
106#endif
107
104/** 108/**
105 * struct iwl_drv - drv common data 109 * struct iwl_drv - drv common data
106 * @list: list of drv structures using this opmode 110 * @list: list of drv structures using this opmode
@@ -126,6 +130,12 @@ struct iwl_drv {
126 char firmware_name[25]; /* name of firmware file to load */ 130 char firmware_name[25]; /* name of firmware file to load */
127 131
128 struct completion request_firmware_complete; 132 struct completion request_firmware_complete;
133
134#ifdef CONFIG_IWLWIFI_DEBUGFS
135 struct dentry *dbgfs_drv;
136 struct dentry *dbgfs_trans;
137 struct dentry *dbgfs_op_mode;
138#endif
129}; 139};
130 140
131#define DVM_OP_MODE 0 141#define DVM_OP_MODE 0
@@ -760,6 +770,50 @@ static int validate_sec_sizes(struct iwl_drv *drv,
760 return 0; 770 return 0;
761} 771}
762 772
773static struct iwl_op_mode *
774_iwl_op_mode_start(struct iwl_drv *drv, struct iwlwifi_opmode_table *op)
775{
776 const struct iwl_op_mode_ops *ops = op->ops;
777 struct dentry *dbgfs_dir = NULL;
778 struct iwl_op_mode *op_mode = NULL;
779
780#ifdef CONFIG_IWLWIFI_DEBUGFS
781 drv->dbgfs_op_mode = debugfs_create_dir(op->name,
782 drv->dbgfs_drv);
783 if (!drv->dbgfs_op_mode) {
784 IWL_ERR(drv,
785 "failed to create opmode debugfs directory\n");
786 return op_mode;
787 }
788 dbgfs_dir = drv->dbgfs_op_mode;
789#endif
790
791 op_mode = ops->start(drv->trans, drv->cfg, &drv->fw, dbgfs_dir);
792
793#ifdef CONFIG_IWLWIFI_DEBUGFS
794 if (!op_mode) {
795 debugfs_remove_recursive(drv->dbgfs_op_mode);
796 drv->dbgfs_op_mode = NULL;
797 }
798#endif
799
800 return op_mode;
801}
802
803static void _iwl_op_mode_stop(struct iwl_drv *drv)
804{
805 /* op_mode can be NULL if its start failed */
806 if (drv->op_mode) {
807 iwl_op_mode_stop(drv->op_mode);
808 drv->op_mode = NULL;
809
810#ifdef CONFIG_IWLWIFI_DEBUGFS
811 debugfs_remove_recursive(drv->dbgfs_op_mode);
812 drv->dbgfs_op_mode = NULL;
813#endif
814 }
815}
816
763/** 817/**
764 * iwl_req_fw_callback - callback when firmware was loaded 818 * iwl_req_fw_callback - callback when firmware was loaded
765 * 819 *
@@ -909,8 +963,7 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
909 list_add_tail(&drv->list, &op->drv); 963 list_add_tail(&drv->list, &op->drv);
910 964
911 if (op->ops) { 965 if (op->ops) {
912 const struct iwl_op_mode_ops *ops = op->ops; 966 drv->op_mode = _iwl_op_mode_start(drv, op);
913 drv->op_mode = ops->start(drv->trans, drv->cfg, &drv->fw);
914 967
915 if (!drv->op_mode) { 968 if (!drv->op_mode) {
916 mutex_unlock(&iwlwifi_opmode_table_mtx); 969 mutex_unlock(&iwlwifi_opmode_table_mtx);
@@ -970,24 +1023,51 @@ struct iwl_drv *iwl_drv_start(struct iwl_trans *trans,
970 init_completion(&drv->request_firmware_complete); 1023 init_completion(&drv->request_firmware_complete);
971 INIT_LIST_HEAD(&drv->list); 1024 INIT_LIST_HEAD(&drv->list);
972 1025
1026#ifdef CONFIG_IWLWIFI_DEBUGFS
1027 /* Create the device debugfs entries. */
1028 drv->dbgfs_drv = debugfs_create_dir(dev_name(trans->dev),
1029 iwl_dbgfs_root);
1030
1031 if (!drv->dbgfs_drv) {
1032 IWL_ERR(drv, "failed to create debugfs directory\n");
1033 goto err_free_drv;
1034 }
1035
1036 /* Create transport layer debugfs dir */
1037 drv->trans->dbgfs_dir = debugfs_create_dir("trans", drv->dbgfs_drv);
1038
1039 if (!drv->trans->dbgfs_dir) {
1040 IWL_ERR(drv, "failed to create transport debugfs directory\n");
1041 goto err_free_dbgfs;
1042 }
1043#endif
1044
973 ret = iwl_request_firmware(drv, true); 1045 ret = iwl_request_firmware(drv, true);
974 1046
975 if (ret) { 1047 if (ret) {
976 IWL_ERR(trans, "Couldn't request the fw\n"); 1048 IWL_ERR(trans, "Couldn't request the fw\n");
977 kfree(drv); 1049 goto err_fw;
978 drv = NULL;
979 } 1050 }
980 1051
981 return drv; 1052 return drv;
1053
1054err_fw:
1055#ifdef CONFIG_IWLWIFI_DEBUGFS
1056err_free_dbgfs:
1057 debugfs_remove_recursive(drv->dbgfs_drv);
1058err_free_drv:
1059#endif
1060 kfree(drv);
1061 drv = NULL;
1062
1063 return drv;
982} 1064}
983 1065
984void iwl_drv_stop(struct iwl_drv *drv) 1066void iwl_drv_stop(struct iwl_drv *drv)
985{ 1067{
986 wait_for_completion(&drv->request_firmware_complete); 1068 wait_for_completion(&drv->request_firmware_complete);
987 1069
988 /* op_mode can be NULL if its start failed */ 1070 _iwl_op_mode_stop(drv);
989 if (drv->op_mode)
990 iwl_op_mode_stop(drv->op_mode);
991 1071
992 iwl_dealloc_ucode(drv); 1072 iwl_dealloc_ucode(drv);
993 1073
@@ -1001,6 +1081,10 @@ void iwl_drv_stop(struct iwl_drv *drv)
1001 list_del(&drv->list); 1081 list_del(&drv->list);
1002 mutex_unlock(&iwlwifi_opmode_table_mtx); 1082 mutex_unlock(&iwlwifi_opmode_table_mtx);
1003 1083
1084#ifdef CONFIG_IWLWIFI_DEBUGFS
1085 debugfs_remove_recursive(drv->dbgfs_drv);
1086#endif
1087
1004 kfree(drv); 1088 kfree(drv);
1005} 1089}
1006 1090
@@ -1023,15 +1107,18 @@ int iwl_opmode_register(const char *name, const struct iwl_op_mode_ops *ops)
1023{ 1107{
1024 int i; 1108 int i;
1025 struct iwl_drv *drv; 1109 struct iwl_drv *drv;
1110 struct iwlwifi_opmode_table *op;
1026 1111
1027 mutex_lock(&iwlwifi_opmode_table_mtx); 1112 mutex_lock(&iwlwifi_opmode_table_mtx);
1028 for (i = 0; i < ARRAY_SIZE(iwlwifi_opmode_table); i++) { 1113 for (i = 0; i < ARRAY_SIZE(iwlwifi_opmode_table); i++) {
1029 if (strcmp(iwlwifi_opmode_table[i].name, name)) 1114 op = &iwlwifi_opmode_table[i];
1115 if (strcmp(op->name, name))
1030 continue; 1116 continue;
1031 iwlwifi_opmode_table[i].ops = ops; 1117 op->ops = ops;
1032 list_for_each_entry(drv, &iwlwifi_opmode_table[i].drv, list) 1118 /* TODO: need to handle exceptional case */
1033 drv->op_mode = ops->start(drv->trans, drv->cfg, 1119 list_for_each_entry(drv, &op->drv, list)
1034 &drv->fw); 1120 drv->op_mode = _iwl_op_mode_start(drv, op);
1121
1035 mutex_unlock(&iwlwifi_opmode_table_mtx); 1122 mutex_unlock(&iwlwifi_opmode_table_mtx);
1036 return 0; 1123 return 0;
1037 } 1124 }
@@ -1052,12 +1139,9 @@ void iwl_opmode_deregister(const char *name)
1052 iwlwifi_opmode_table[i].ops = NULL; 1139 iwlwifi_opmode_table[i].ops = NULL;
1053 1140
1054 /* call the stop routine for all devices */ 1141 /* call the stop routine for all devices */
1055 list_for_each_entry(drv, &iwlwifi_opmode_table[i].drv, list) { 1142 list_for_each_entry(drv, &iwlwifi_opmode_table[i].drv, list)
1056 if (drv->op_mode) { 1143 _iwl_op_mode_stop(drv);
1057 iwl_op_mode_stop(drv->op_mode); 1144
1058 drv->op_mode = NULL;
1059 }
1060 }
1061 mutex_unlock(&iwlwifi_opmode_table_mtx); 1145 mutex_unlock(&iwlwifi_opmode_table_mtx);
1062 return; 1146 return;
1063 } 1147 }
@@ -1077,6 +1161,14 @@ static int __init iwl_drv_init(void)
1077 pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n"); 1161 pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n");
1078 pr_info(DRV_COPYRIGHT "\n"); 1162 pr_info(DRV_COPYRIGHT "\n");
1079 1163
1164#ifdef CONFIG_IWLWIFI_DEBUGFS
1165 /* Create the root of iwlwifi debugfs subsystem. */
1166 iwl_dbgfs_root = debugfs_create_dir(DRV_NAME, NULL);
1167
1168 if (!iwl_dbgfs_root)
1169 return -EFAULT;
1170#endif
1171
1080 return iwl_pci_register_driver(); 1172 return iwl_pci_register_driver();
1081} 1173}
1082module_init(iwl_drv_init); 1174module_init(iwl_drv_init);
@@ -1084,6 +1176,10 @@ module_init(iwl_drv_init);
1084static void __exit iwl_drv_exit(void) 1176static void __exit iwl_drv_exit(void)
1085{ 1177{
1086 iwl_pci_unregister_driver(); 1178 iwl_pci_unregister_driver();
1179
1180#ifdef CONFIG_IWLWIFI_DEBUGFS
1181 debugfs_remove_recursive(iwl_dbgfs_root);
1182#endif
1087} 1183}
1088module_exit(iwl_drv_exit); 1184module_exit(iwl_drv_exit);
1089 1185