0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117 #include <linux/debugfs.h>
0118 #include <linux/module.h>
0119 #include <linux/slab.h>
0120
0121 #include "xgbe.h"
0122 #include "xgbe-common.h"
0123
0124 static ssize_t xgbe_common_read(char __user *buffer, size_t count,
0125 loff_t *ppos, unsigned int value)
0126 {
0127 char *buf;
0128 ssize_t len;
0129
0130 if (*ppos != 0)
0131 return 0;
0132
0133 buf = kasprintf(GFP_KERNEL, "0x%08x\n", value);
0134 if (!buf)
0135 return -ENOMEM;
0136
0137 if (count < strlen(buf)) {
0138 kfree(buf);
0139 return -ENOSPC;
0140 }
0141
0142 len = simple_read_from_buffer(buffer, count, ppos, buf, strlen(buf));
0143 kfree(buf);
0144
0145 return len;
0146 }
0147
0148 static ssize_t xgbe_common_write(const char __user *buffer, size_t count,
0149 loff_t *ppos, unsigned int *value)
0150 {
0151 char workarea[32];
0152 ssize_t len;
0153 int ret;
0154
0155 if (*ppos != 0)
0156 return -EINVAL;
0157
0158 if (count >= sizeof(workarea))
0159 return -ENOSPC;
0160
0161 len = simple_write_to_buffer(workarea, sizeof(workarea) - 1, ppos,
0162 buffer, count);
0163 if (len < 0)
0164 return len;
0165
0166 workarea[len] = '\0';
0167 ret = kstrtouint(workarea, 16, value);
0168 if (ret)
0169 return -EIO;
0170
0171 return len;
0172 }
0173
0174 static ssize_t xgmac_reg_addr_read(struct file *filp, char __user *buffer,
0175 size_t count, loff_t *ppos)
0176 {
0177 struct xgbe_prv_data *pdata = filp->private_data;
0178
0179 return xgbe_common_read(buffer, count, ppos, pdata->debugfs_xgmac_reg);
0180 }
0181
0182 static ssize_t xgmac_reg_addr_write(struct file *filp,
0183 const char __user *buffer,
0184 size_t count, loff_t *ppos)
0185 {
0186 struct xgbe_prv_data *pdata = filp->private_data;
0187
0188 return xgbe_common_write(buffer, count, ppos,
0189 &pdata->debugfs_xgmac_reg);
0190 }
0191
0192 static ssize_t xgmac_reg_value_read(struct file *filp, char __user *buffer,
0193 size_t count, loff_t *ppos)
0194 {
0195 struct xgbe_prv_data *pdata = filp->private_data;
0196 unsigned int value;
0197
0198 value = XGMAC_IOREAD(pdata, pdata->debugfs_xgmac_reg);
0199
0200 return xgbe_common_read(buffer, count, ppos, value);
0201 }
0202
0203 static ssize_t xgmac_reg_value_write(struct file *filp,
0204 const char __user *buffer,
0205 size_t count, loff_t *ppos)
0206 {
0207 struct xgbe_prv_data *pdata = filp->private_data;
0208 unsigned int value;
0209 ssize_t len;
0210
0211 len = xgbe_common_write(buffer, count, ppos, &value);
0212 if (len < 0)
0213 return len;
0214
0215 XGMAC_IOWRITE(pdata, pdata->debugfs_xgmac_reg, value);
0216
0217 return len;
0218 }
0219
0220 static const struct file_operations xgmac_reg_addr_fops = {
0221 .owner = THIS_MODULE,
0222 .open = simple_open,
0223 .read = xgmac_reg_addr_read,
0224 .write = xgmac_reg_addr_write,
0225 };
0226
0227 static const struct file_operations xgmac_reg_value_fops = {
0228 .owner = THIS_MODULE,
0229 .open = simple_open,
0230 .read = xgmac_reg_value_read,
0231 .write = xgmac_reg_value_write,
0232 };
0233
0234 static ssize_t xpcs_mmd_read(struct file *filp, char __user *buffer,
0235 size_t count, loff_t *ppos)
0236 {
0237 struct xgbe_prv_data *pdata = filp->private_data;
0238
0239 return xgbe_common_read(buffer, count, ppos, pdata->debugfs_xpcs_mmd);
0240 }
0241
0242 static ssize_t xpcs_mmd_write(struct file *filp, const char __user *buffer,
0243 size_t count, loff_t *ppos)
0244 {
0245 struct xgbe_prv_data *pdata = filp->private_data;
0246
0247 return xgbe_common_write(buffer, count, ppos,
0248 &pdata->debugfs_xpcs_mmd);
0249 }
0250
0251 static ssize_t xpcs_reg_addr_read(struct file *filp, char __user *buffer,
0252 size_t count, loff_t *ppos)
0253 {
0254 struct xgbe_prv_data *pdata = filp->private_data;
0255
0256 return xgbe_common_read(buffer, count, ppos, pdata->debugfs_xpcs_reg);
0257 }
0258
0259 static ssize_t xpcs_reg_addr_write(struct file *filp, const char __user *buffer,
0260 size_t count, loff_t *ppos)
0261 {
0262 struct xgbe_prv_data *pdata = filp->private_data;
0263
0264 return xgbe_common_write(buffer, count, ppos,
0265 &pdata->debugfs_xpcs_reg);
0266 }
0267
0268 static ssize_t xpcs_reg_value_read(struct file *filp, char __user *buffer,
0269 size_t count, loff_t *ppos)
0270 {
0271 struct xgbe_prv_data *pdata = filp->private_data;
0272 unsigned int value;
0273
0274 value = XMDIO_READ(pdata, pdata->debugfs_xpcs_mmd,
0275 pdata->debugfs_xpcs_reg);
0276
0277 return xgbe_common_read(buffer, count, ppos, value);
0278 }
0279
0280 static ssize_t xpcs_reg_value_write(struct file *filp,
0281 const char __user *buffer,
0282 size_t count, loff_t *ppos)
0283 {
0284 struct xgbe_prv_data *pdata = filp->private_data;
0285 unsigned int value;
0286 ssize_t len;
0287
0288 len = xgbe_common_write(buffer, count, ppos, &value);
0289 if (len < 0)
0290 return len;
0291
0292 XMDIO_WRITE(pdata, pdata->debugfs_xpcs_mmd, pdata->debugfs_xpcs_reg,
0293 value);
0294
0295 return len;
0296 }
0297
0298 static const struct file_operations xpcs_mmd_fops = {
0299 .owner = THIS_MODULE,
0300 .open = simple_open,
0301 .read = xpcs_mmd_read,
0302 .write = xpcs_mmd_write,
0303 };
0304
0305 static const struct file_operations xpcs_reg_addr_fops = {
0306 .owner = THIS_MODULE,
0307 .open = simple_open,
0308 .read = xpcs_reg_addr_read,
0309 .write = xpcs_reg_addr_write,
0310 };
0311
0312 static const struct file_operations xpcs_reg_value_fops = {
0313 .owner = THIS_MODULE,
0314 .open = simple_open,
0315 .read = xpcs_reg_value_read,
0316 .write = xpcs_reg_value_write,
0317 };
0318
0319 static ssize_t xprop_reg_addr_read(struct file *filp, char __user *buffer,
0320 size_t count, loff_t *ppos)
0321 {
0322 struct xgbe_prv_data *pdata = filp->private_data;
0323
0324 return xgbe_common_read(buffer, count, ppos, pdata->debugfs_xprop_reg);
0325 }
0326
0327 static ssize_t xprop_reg_addr_write(struct file *filp,
0328 const char __user *buffer,
0329 size_t count, loff_t *ppos)
0330 {
0331 struct xgbe_prv_data *pdata = filp->private_data;
0332
0333 return xgbe_common_write(buffer, count, ppos,
0334 &pdata->debugfs_xprop_reg);
0335 }
0336
0337 static ssize_t xprop_reg_value_read(struct file *filp, char __user *buffer,
0338 size_t count, loff_t *ppos)
0339 {
0340 struct xgbe_prv_data *pdata = filp->private_data;
0341 unsigned int value;
0342
0343 value = XP_IOREAD(pdata, pdata->debugfs_xprop_reg);
0344
0345 return xgbe_common_read(buffer, count, ppos, value);
0346 }
0347
0348 static ssize_t xprop_reg_value_write(struct file *filp,
0349 const char __user *buffer,
0350 size_t count, loff_t *ppos)
0351 {
0352 struct xgbe_prv_data *pdata = filp->private_data;
0353 unsigned int value;
0354 ssize_t len;
0355
0356 len = xgbe_common_write(buffer, count, ppos, &value);
0357 if (len < 0)
0358 return len;
0359
0360 XP_IOWRITE(pdata, pdata->debugfs_xprop_reg, value);
0361
0362 return len;
0363 }
0364
0365 static const struct file_operations xprop_reg_addr_fops = {
0366 .owner = THIS_MODULE,
0367 .open = simple_open,
0368 .read = xprop_reg_addr_read,
0369 .write = xprop_reg_addr_write,
0370 };
0371
0372 static const struct file_operations xprop_reg_value_fops = {
0373 .owner = THIS_MODULE,
0374 .open = simple_open,
0375 .read = xprop_reg_value_read,
0376 .write = xprop_reg_value_write,
0377 };
0378
0379 static ssize_t xi2c_reg_addr_read(struct file *filp, char __user *buffer,
0380 size_t count, loff_t *ppos)
0381 {
0382 struct xgbe_prv_data *pdata = filp->private_data;
0383
0384 return xgbe_common_read(buffer, count, ppos, pdata->debugfs_xi2c_reg);
0385 }
0386
0387 static ssize_t xi2c_reg_addr_write(struct file *filp,
0388 const char __user *buffer,
0389 size_t count, loff_t *ppos)
0390 {
0391 struct xgbe_prv_data *pdata = filp->private_data;
0392
0393 return xgbe_common_write(buffer, count, ppos,
0394 &pdata->debugfs_xi2c_reg);
0395 }
0396
0397 static ssize_t xi2c_reg_value_read(struct file *filp, char __user *buffer,
0398 size_t count, loff_t *ppos)
0399 {
0400 struct xgbe_prv_data *pdata = filp->private_data;
0401 unsigned int value;
0402
0403 value = XI2C_IOREAD(pdata, pdata->debugfs_xi2c_reg);
0404
0405 return xgbe_common_read(buffer, count, ppos, value);
0406 }
0407
0408 static ssize_t xi2c_reg_value_write(struct file *filp,
0409 const char __user *buffer,
0410 size_t count, loff_t *ppos)
0411 {
0412 struct xgbe_prv_data *pdata = filp->private_data;
0413 unsigned int value;
0414 ssize_t len;
0415
0416 len = xgbe_common_write(buffer, count, ppos, &value);
0417 if (len < 0)
0418 return len;
0419
0420 XI2C_IOWRITE(pdata, pdata->debugfs_xi2c_reg, value);
0421
0422 return len;
0423 }
0424
0425 static const struct file_operations xi2c_reg_addr_fops = {
0426 .owner = THIS_MODULE,
0427 .open = simple_open,
0428 .read = xi2c_reg_addr_read,
0429 .write = xi2c_reg_addr_write,
0430 };
0431
0432 static const struct file_operations xi2c_reg_value_fops = {
0433 .owner = THIS_MODULE,
0434 .open = simple_open,
0435 .read = xi2c_reg_value_read,
0436 .write = xi2c_reg_value_write,
0437 };
0438
0439 void xgbe_debugfs_init(struct xgbe_prv_data *pdata)
0440 {
0441 char *buf;
0442
0443
0444 pdata->debugfs_xgmac_reg = 0;
0445 pdata->debugfs_xpcs_mmd = 1;
0446 pdata->debugfs_xpcs_reg = 0;
0447
0448 buf = kasprintf(GFP_KERNEL, "amd-xgbe-%s", pdata->netdev->name);
0449 if (!buf)
0450 return;
0451
0452 pdata->xgbe_debugfs = debugfs_create_dir(buf, NULL);
0453
0454 debugfs_create_file("xgmac_register", 0600, pdata->xgbe_debugfs, pdata,
0455 &xgmac_reg_addr_fops);
0456
0457 debugfs_create_file("xgmac_register_value", 0600, pdata->xgbe_debugfs,
0458 pdata, &xgmac_reg_value_fops);
0459
0460 debugfs_create_file("xpcs_mmd", 0600, pdata->xgbe_debugfs, pdata,
0461 &xpcs_mmd_fops);
0462
0463 debugfs_create_file("xpcs_register", 0600, pdata->xgbe_debugfs, pdata,
0464 &xpcs_reg_addr_fops);
0465
0466 debugfs_create_file("xpcs_register_value", 0600, pdata->xgbe_debugfs,
0467 pdata, &xpcs_reg_value_fops);
0468
0469 if (pdata->xprop_regs) {
0470 debugfs_create_file("xprop_register", 0600, pdata->xgbe_debugfs,
0471 pdata, &xprop_reg_addr_fops);
0472
0473 debugfs_create_file("xprop_register_value", 0600,
0474 pdata->xgbe_debugfs, pdata,
0475 &xprop_reg_value_fops);
0476 }
0477
0478 if (pdata->xi2c_regs) {
0479 debugfs_create_file("xi2c_register", 0600, pdata->xgbe_debugfs,
0480 pdata, &xi2c_reg_addr_fops);
0481
0482 debugfs_create_file("xi2c_register_value", 0600,
0483 pdata->xgbe_debugfs, pdata,
0484 &xi2c_reg_value_fops);
0485 }
0486
0487 if (pdata->vdata->an_cdr_workaround) {
0488 debugfs_create_bool("an_cdr_workaround", 0600,
0489 pdata->xgbe_debugfs,
0490 &pdata->debugfs_an_cdr_workaround);
0491
0492 debugfs_create_bool("an_cdr_track_early", 0600,
0493 pdata->xgbe_debugfs,
0494 &pdata->debugfs_an_cdr_track_early);
0495 }
0496
0497 kfree(buf);
0498 }
0499
0500 void xgbe_debugfs_exit(struct xgbe_prv_data *pdata)
0501 {
0502 debugfs_remove_recursive(pdata->xgbe_debugfs);
0503 pdata->xgbe_debugfs = NULL;
0504 }
0505
0506 void xgbe_debugfs_rename(struct xgbe_prv_data *pdata)
0507 {
0508 char *buf;
0509
0510 if (!pdata->xgbe_debugfs)
0511 return;
0512
0513 buf = kasprintf(GFP_KERNEL, "amd-xgbe-%s", pdata->netdev->name);
0514 if (!buf)
0515 return;
0516
0517 if (!strcmp(pdata->xgbe_debugfs->d_name.name, buf))
0518 goto out;
0519
0520 debugfs_rename(pdata->xgbe_debugfs->d_parent, pdata->xgbe_debugfs,
0521 pdata->xgbe_debugfs->d_parent, buf);
0522
0523 out:
0524 kfree(buf);
0525 }