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