1 /* 2 * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /** 21 * DOC: qdf_debugfs.h 22 * This file provides OS abstraction for debug filesystem APIs. 23 */ 24 25 #ifndef _QDF_DEBUGFS_H 26 #define _QDF_DEBUGFS_H 27 28 #include <qdf_status.h> 29 #include <i_qdf_debugfs.h> 30 #include <qdf_atomic.h> 31 #include <qdf_types.h> 32 33 /* representation of qdf dentry */ 34 typedef __qdf_dentry_t qdf_dentry_t; 35 typedef __qdf_debugfs_file_t qdf_debugfs_file_t; 36 typedef __qdf_debugfs_blob_wrap_t qdf_debugfs_blob_wrap_t; 37 typedef __qdf_entry_t qdf_entry_t; 38 typedef __qdf_file_ops_t qdf_file_ops_t; 39 40 /* qdf file modes */ 41 #define QDF_FILE_USR_READ 00400 42 #define QDF_FILE_USR_WRITE 00200 43 44 #define QDF_FILE_GRP_READ 00040 45 #define QDF_FILE_GRP_WRITE 00020 46 47 #define QDF_FILE_OTH_READ 00004 48 #define QDF_FILE_OTH_WRITE 00002 49 50 /** 51 * struct qdf_debugfs_fops - qdf debugfs operations 52 * @show: Callback for show operation. 53 * Following functions can be used to print data in the show function, 54 * qdf_debugfs_print() 55 * qdf_debugfs_hexdump() 56 * qdf_debugfs_write() 57 * @write: Callback for write operation. 58 * @priv: Private pointer which will be passed in the registered callbacks. 59 */ 60 struct qdf_debugfs_fops { 61 QDF_STATUS(*show)(qdf_debugfs_file_t file, void *arg); 62 QDF_STATUS(*write)(void *priv, const char *buf, qdf_size_t len); 63 void *priv; 64 }; 65 66 #ifdef WLAN_DEBUGFS 67 /** 68 * qdf_debugfs_init() - initialize debugfs 69 * 70 * Return: QDF_STATUS 71 */ 72 QDF_STATUS qdf_debugfs_init(void); 73 74 /** 75 * qdf_debugfs_exit() - cleanup debugfs 76 * 77 * Return: None 78 */ 79 void qdf_debugfs_exit(void); 80 81 /** 82 * qdf_debugfs_create_dir() - create a debugfs directory 83 * @name: name of the new directory 84 * @parent: parent node. If NULL, defaults to base qdf_debugfs_root 85 * 86 * Return: dentry structure pointer in case of success, otherwise NULL. 87 * 88 */ 89 qdf_dentry_t qdf_debugfs_create_dir(const char *name, qdf_dentry_t parent); 90 91 /** 92 * qdf_debugfs_create_file() - create a debugfs file 93 * @name: name of the file 94 * @mode: qdf file mode 95 * @parent: parent node. If NULL, defaults to base qdf_debugfs_root 96 * @fops: file operations { .read, .write ... } 97 * 98 * Return: dentry structure pointer in case of success, otherwise NULL. 99 * 100 */ 101 qdf_dentry_t qdf_debugfs_create_file(const char *name, uint16_t mode, 102 qdf_dentry_t parent, 103 struct qdf_debugfs_fops *fops); 104 105 /** 106 * qdf_debugfs_printf() - print formatted string into debugfs file 107 * @file: debugfs file handle passed in fops->show() function 108 * @f: the format string to use 109 * @...: arguments for the format string 110 */ 111 void qdf_debugfs_printf(qdf_debugfs_file_t file, const char *f, ...); 112 113 /** 114 * qdf_debugfs_hexdump() - print hexdump into debugfs file 115 * @file: debugfs file handle passed in fops->show() function. 116 * @buf: data 117 * @len: data length 118 * @rowsize: row size in bytes to dump 119 * @groupsize: group size in bytes to dump 120 * 121 */ 122 void qdf_debugfs_hexdump(qdf_debugfs_file_t file, const uint8_t *buf, 123 qdf_size_t len, int rowsize, int groupsize); 124 125 /** 126 * qdf_debugfs_overflow() - check overflow occurrence in debugfs buffer 127 * @file: debugfs file handle passed in fops->show() function. 128 * 129 * Return: 1 on overflow occurrence else 0 130 * 131 */ 132 bool qdf_debugfs_overflow(qdf_debugfs_file_t file); 133 134 /** 135 * qdf_debugfs_write() - write data into debugfs file 136 * @file: debugfs file handle passed in fops->show() function. 137 * @buf: data 138 * @len: data length 139 * 140 */ 141 void qdf_debugfs_write(qdf_debugfs_file_t file, const uint8_t *buf, 142 qdf_size_t len); 143 144 /** 145 * qdf_debugfs_create_u8() - create a debugfs file for a u8 variable 146 * @name: name of the file 147 * @mode: qdf file mode 148 * @parent: parent node. If NULL, defaults to base 'qdf_debugfs_root' 149 * @value: pointer to a u8 variable (global/static) 150 * 151 * Return: None 152 */ 153 void qdf_debugfs_create_u8(const char *name, uint16_t mode, 154 qdf_dentry_t parent, u8 *value); 155 156 /** 157 * qdf_debugfs_create_u16() - create a debugfs file for a u16 variable 158 * @name: name of the file 159 * @mode: qdf file mode 160 * @parent: parent node. If NULL, defaults to base 'qdf_debugfs_root' 161 * @value: pointer to a u16 variable (global/static) 162 * 163 * Return: None 164 */ 165 void qdf_debugfs_create_u16(const char *name, uint16_t mode, 166 qdf_dentry_t parent, u16 *value); 167 168 /** 169 * qdf_debugfs_create_u32() - create a debugfs file for a u32 variable 170 * @name: name of the file 171 * @mode: qdf file mode 172 * @parent: parent node. If NULL, defaults to base 'qdf_debugfs_root' 173 * @value: pointer to a u32 variable (global/static) 174 * 175 * Return: None 176 */ 177 void qdf_debugfs_create_u32(const char *name, uint16_t mode, 178 qdf_dentry_t parent, u32 *value); 179 180 /** 181 * qdf_debugfs_create_u64() - create a debugfs file for a u64 variable 182 * @name: name of the file 183 * @mode: qdf file mode 184 * @parent: parent node. If NULL, defaults to base 'qdf_debugfs_root' 185 * @value: pointer to a u64 variable (global/static) 186 * 187 * Return: None 188 */ 189 void qdf_debugfs_create_u64(const char *name, uint16_t mode, 190 qdf_dentry_t parent, u64 *value); 191 192 /** 193 * qdf_debugfs_create_atomic() - create a debugfs file for an atomic variable 194 * @name: name of the file 195 * @mode: qdf file mode 196 * @parent: parent node. If NULL, defaults to base 'qdf_debugfs_root' 197 * @value: pointer to an atomic variable (global/static) 198 * 199 * Return: None 200 */ 201 void qdf_debugfs_create_atomic(const char *name, uint16_t mode, 202 qdf_dentry_t parent, 203 qdf_atomic_t *value); 204 205 /** 206 * qdf_debugfs_create_string() - create a debugfs file for a string 207 * @name: name of the file 208 * @mode: qdf file mode 209 * @parent: parent node. If NULL, defaults to base 'qdf_debugfs_root' 210 * @str: a pointer to NULL terminated string (global/static). 211 * 212 * Return: dentry for the file; NULL in case of failure. 213 * 214 */ 215 qdf_dentry_t qdf_debugfs_create_string(const char *name, uint16_t mode, 216 qdf_dentry_t parent, char *str); 217 218 /** 219 * qdf_debugfs_remove_dir_recursive() - remove directory recursively 220 * @d: debugfs node 221 * 222 * This function will recursively removes a dreictory in debugfs that was 223 * previously createed with a call to qdf_debugfs_create_file() or it's 224 * variant functions. 225 */ 226 void qdf_debugfs_remove_dir_recursive(qdf_dentry_t d); 227 228 /** 229 * qdf_debugfs_remove_dir() - remove debugfs directory 230 * @d: debugfs node 231 * 232 */ 233 void qdf_debugfs_remove_dir(qdf_dentry_t d); 234 235 /** 236 * qdf_debugfs_remove_file() - remove debugfs file 237 * @d: debugfs node 238 * 239 */ 240 void qdf_debugfs_remove_file(qdf_dentry_t d); 241 242 /** 243 * qdf_debugfs_create_file_simplified() - Create a simple debugfs file 244 * where a single function call produces all the desired output 245 * @name: name of the file 246 * @mode: qdf file mode 247 * @parent: parent node. If NULL, defaults to base 'qdf_debugfs_root' 248 * @fops: file operations { .show, .write , .priv... } 249 * 250 * Users just have to define the show() function and pass it via @fops.show() 251 * argument. When the output time comes, the show() will be called once. 252 * The show() function must do everything that is needed to write the data, 253 * all in one function call. 254 * This is useful either for writing small amounts of data to debugfs or 255 * for cases in which the output is not iterative. 256 * The private data can be passed via @fops.priv, which will be available 257 * inside the show() function as the 'private' filed of the qdf_debugfs_file_t. 258 * 259 * Return: dentry structure pointer in case of success, otherwise NULL. 260 * 261 */ 262 263 qdf_dentry_t qdf_debugfs_create_file_simplified(const char *name, uint16_t mode, 264 qdf_dentry_t parent, 265 struct qdf_debugfs_fops *fops); 266 267 /** 268 * qdf_debugfs_printer() - Print formatted string into debugfs file 269 * @priv: The private data 270 * @fmt: Format string 271 * @...: arguments for the format string 272 * 273 * This function prints a new line character after printing the formatted 274 * string into the debugfs file. 275 * This function can be passed when the argument is of type qdf_abstract_print 276 */ 277 int qdf_debugfs_printer(void *priv, const char *fmt, ...); 278 279 /** 280 * qdf_debugfs_create_blob() - create a debugfs file that is used to read 281 * a binary blob 282 * @name: a pointer to a string containing the name of the file to create. 283 * @mode: the permission that the file should have 284 * @parent: a pointer to the parent dentry for this file. This should be a 285 * directory dentry if set. If this parameter is %NULL, then the 286 * file will be created in the root of the debugfs filesystem. 287 * @blob: a pointer to a qdf_debugfs_blob_wrap_t which contains a pointer 288 * to the blob data and the size of the data. 289 * 290 * Return: dentry structure pointer on success, NULL otherwise. 291 */ 292 qdf_dentry_t qdf_debugfs_create_blob(const char *name, umode_t mode, 293 qdf_dentry_t parent, 294 qdf_debugfs_blob_wrap_t blob); 295 296 /** 297 * qdf_debugfs_create_entry() - create a debugfs file for read or write 298 * something 299 * @name: name of the file 300 * @mode: qdf file mode 301 * @parent: parent node. If NULL, defaults to base qdf_debugfs_root 302 * @data: Something data that caller want to read or write 303 * @fops: file operations { .read, .write ... } 304 * 305 * Return: dentry structure pointer on success, NULL otherwise. 306 */ 307 qdf_dentry_t qdf_debugfs_create_entry(const char *name, uint16_t mode, 308 qdf_dentry_t parent, 309 qdf_entry_t data, 310 const qdf_file_ops_t fops); 311 312 #else /* WLAN_DEBUGFS */ 313 314 static inline QDF_STATUS qdf_debugfs_init(void) 315 { 316 return QDF_STATUS_SUCCESS; 317 } 318 319 static inline void qdf_debugfs_exit(void) { } 320 321 static inline qdf_dentry_t qdf_debugfs_create_dir(const char *name, 322 qdf_dentry_t parent) 323 { 324 return NULL; 325 } 326 327 static inline qdf_dentry_t 328 qdf_debugfs_create_file(const char *name, uint16_t mode, qdf_dentry_t parent, 329 struct qdf_debugfs_fops *fops) 330 { 331 return NULL; 332 } 333 334 static inline void qdf_debugfs_printf(qdf_debugfs_file_t file, const char *f, 335 ...) 336 { 337 } 338 339 static inline void qdf_debugfs_hexdump(qdf_debugfs_file_t file, 340 const uint8_t *buf, qdf_size_t len, 341 int rowsize, int groupsize) 342 { 343 } 344 345 static inline bool qdf_debugfs_overflow(qdf_debugfs_file_t file) 346 { 347 return 0; 348 } 349 350 static inline void qdf_debugfs_write(qdf_debugfs_file_t file, 351 const uint8_t *buf, qdf_size_t len) 352 { 353 } 354 355 static inline void qdf_debugfs_create_u8(const char *name, 356 uint16_t mode, 357 qdf_dentry_t parent, u8 *value) 358 { 359 } 360 361 static inline void qdf_debugfs_create_u16(const char *name, 362 uint16_t mode, 363 qdf_dentry_t parent, 364 u16 *value) 365 { 366 } 367 368 static inline void qdf_debugfs_create_u32(const char *name, 369 uint16_t mode, 370 qdf_dentry_t parent, 371 u32 *value) 372 { 373 } 374 375 static inline void qdf_debugfs_create_u64(const char *name, 376 uint16_t mode, 377 qdf_dentry_t parent, 378 u64 *value) 379 { 380 } 381 382 static inline void qdf_debugfs_create_atomic(const char *name, 383 uint16_t mode, 384 qdf_dentry_t parent, 385 qdf_atomic_t *value) 386 { 387 } 388 389 static inline qdf_dentry_t debugfs_create_string(const char *name, 390 uint16_t mode, 391 qdf_dentry_t parent, char *str) 392 { 393 return NULL; 394 } 395 396 static inline void qdf_debugfs_remove_dir_recursive(qdf_dentry_t d) {} 397 static inline void qdf_debugfs_remove_dir(qdf_dentry_t d) {} 398 static inline void qdf_debugfs_remove_file(qdf_dentry_t d) {} 399 400 static inline 401 qdf_dentry_t qdf_debugfs_create_file_simplified(const char *name, uint16_t mode, 402 qdf_dentry_t parent, 403 struct qdf_debugfs_fops *fops) 404 { 405 return NULL; 406 } 407 408 static inline 409 int qdf_debugfs_printer(void *priv, const char *fmt, ...) 410 { 411 return 0; 412 } 413 414 static inline 415 qdf_dentry_t qdf_debugfs_create_blob(const char *name, umode_t mode, 416 qdf_dentry_t parent, 417 qdf_debugfs_blob_wrap_t blob) 418 { 419 return NULL; 420 } 421 422 static inline 423 qdf_dentry_t qdf_debugfs_create_entry(const char *name, uint16_t mode, 424 qdf_dentry_t parent, 425 qdf_entry_t data, 426 const qdf_file_ops_t fops) 427 { 428 return NULL; 429 } 430 #endif /* WLAN_DEBUGFS */ 431 #endif /* _QDF_DEBUGFS_H */ 432