xref: /OK3568_Linux_fs/kernel/net/atm/atm_sysfs.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /* ATM driver model support. */
3*4882a593Smuzhiyun 
4*4882a593Smuzhiyun #include <linux/kernel.h>
5*4882a593Smuzhiyun #include <linux/slab.h>
6*4882a593Smuzhiyun #include <linux/init.h>
7*4882a593Smuzhiyun #include <linux/kobject.h>
8*4882a593Smuzhiyun #include <linux/atmdev.h>
9*4882a593Smuzhiyun #include "common.h"
10*4882a593Smuzhiyun #include "resources.h"
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #define to_atm_dev(cldev) container_of(cldev, struct atm_dev, class_dev)
13*4882a593Smuzhiyun 
show_type(struct device * cdev,struct device_attribute * attr,char * buf)14*4882a593Smuzhiyun static ssize_t show_type(struct device *cdev,
15*4882a593Smuzhiyun 			 struct device_attribute *attr, char *buf)
16*4882a593Smuzhiyun {
17*4882a593Smuzhiyun 	struct atm_dev *adev = to_atm_dev(cdev);
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun 	return scnprintf(buf, PAGE_SIZE, "%s\n", adev->type);
20*4882a593Smuzhiyun }
21*4882a593Smuzhiyun 
show_address(struct device * cdev,struct device_attribute * attr,char * buf)22*4882a593Smuzhiyun static ssize_t show_address(struct device *cdev,
23*4882a593Smuzhiyun 			    struct device_attribute *attr, char *buf)
24*4882a593Smuzhiyun {
25*4882a593Smuzhiyun 	struct atm_dev *adev = to_atm_dev(cdev);
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun 	return scnprintf(buf, PAGE_SIZE, "%pM\n", adev->esi);
28*4882a593Smuzhiyun }
29*4882a593Smuzhiyun 
show_atmaddress(struct device * cdev,struct device_attribute * attr,char * buf)30*4882a593Smuzhiyun static ssize_t show_atmaddress(struct device *cdev,
31*4882a593Smuzhiyun 			       struct device_attribute *attr, char *buf)
32*4882a593Smuzhiyun {
33*4882a593Smuzhiyun 	unsigned long flags;
34*4882a593Smuzhiyun 	struct atm_dev *adev = to_atm_dev(cdev);
35*4882a593Smuzhiyun 	struct atm_dev_addr *aaddr;
36*4882a593Smuzhiyun 	int count = 0;
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun 	spin_lock_irqsave(&adev->lock, flags);
39*4882a593Smuzhiyun 	list_for_each_entry(aaddr, &adev->local, entry) {
40*4882a593Smuzhiyun 		count += scnprintf(buf + count, PAGE_SIZE - count,
41*4882a593Smuzhiyun 				   "%1phN.%2phN.%10phN.%6phN.%1phN\n",
42*4882a593Smuzhiyun 				   &aaddr->addr.sas_addr.prv[0],
43*4882a593Smuzhiyun 				   &aaddr->addr.sas_addr.prv[1],
44*4882a593Smuzhiyun 				   &aaddr->addr.sas_addr.prv[3],
45*4882a593Smuzhiyun 				   &aaddr->addr.sas_addr.prv[13],
46*4882a593Smuzhiyun 				   &aaddr->addr.sas_addr.prv[19]);
47*4882a593Smuzhiyun 	}
48*4882a593Smuzhiyun 	spin_unlock_irqrestore(&adev->lock, flags);
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun 	return count;
51*4882a593Smuzhiyun }
52*4882a593Smuzhiyun 
show_atmindex(struct device * cdev,struct device_attribute * attr,char * buf)53*4882a593Smuzhiyun static ssize_t show_atmindex(struct device *cdev,
54*4882a593Smuzhiyun 			     struct device_attribute *attr, char *buf)
55*4882a593Smuzhiyun {
56*4882a593Smuzhiyun 	struct atm_dev *adev = to_atm_dev(cdev);
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun 	return scnprintf(buf, PAGE_SIZE, "%d\n", adev->number);
59*4882a593Smuzhiyun }
60*4882a593Smuzhiyun 
show_carrier(struct device * cdev,struct device_attribute * attr,char * buf)61*4882a593Smuzhiyun static ssize_t show_carrier(struct device *cdev,
62*4882a593Smuzhiyun 			    struct device_attribute *attr, char *buf)
63*4882a593Smuzhiyun {
64*4882a593Smuzhiyun 	struct atm_dev *adev = to_atm_dev(cdev);
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun 	return scnprintf(buf, PAGE_SIZE, "%d\n",
67*4882a593Smuzhiyun 			 adev->signal == ATM_PHY_SIG_LOST ? 0 : 1);
68*4882a593Smuzhiyun }
69*4882a593Smuzhiyun 
show_link_rate(struct device * cdev,struct device_attribute * attr,char * buf)70*4882a593Smuzhiyun static ssize_t show_link_rate(struct device *cdev,
71*4882a593Smuzhiyun 			      struct device_attribute *attr, char *buf)
72*4882a593Smuzhiyun {
73*4882a593Smuzhiyun 	struct atm_dev *adev = to_atm_dev(cdev);
74*4882a593Smuzhiyun 	int link_rate;
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun 	/* show the link rate, not the data rate */
77*4882a593Smuzhiyun 	switch (adev->link_rate) {
78*4882a593Smuzhiyun 	case ATM_OC3_PCR:
79*4882a593Smuzhiyun 		link_rate = 155520000;
80*4882a593Smuzhiyun 		break;
81*4882a593Smuzhiyun 	case ATM_OC12_PCR:
82*4882a593Smuzhiyun 		link_rate = 622080000;
83*4882a593Smuzhiyun 		break;
84*4882a593Smuzhiyun 	case ATM_25_PCR:
85*4882a593Smuzhiyun 		link_rate = 25600000;
86*4882a593Smuzhiyun 		break;
87*4882a593Smuzhiyun 	default:
88*4882a593Smuzhiyun 		link_rate = adev->link_rate * 8 * 53;
89*4882a593Smuzhiyun 	}
90*4882a593Smuzhiyun 	return scnprintf(buf, PAGE_SIZE, "%d\n", link_rate);
91*4882a593Smuzhiyun }
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun static DEVICE_ATTR(address, 0444, show_address, NULL);
94*4882a593Smuzhiyun static DEVICE_ATTR(atmaddress, 0444, show_atmaddress, NULL);
95*4882a593Smuzhiyun static DEVICE_ATTR(atmindex, 0444, show_atmindex, NULL);
96*4882a593Smuzhiyun static DEVICE_ATTR(carrier, 0444, show_carrier, NULL);
97*4882a593Smuzhiyun static DEVICE_ATTR(type, 0444, show_type, NULL);
98*4882a593Smuzhiyun static DEVICE_ATTR(link_rate, 0444, show_link_rate, NULL);
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun static struct device_attribute *atm_attrs[] = {
101*4882a593Smuzhiyun 	&dev_attr_atmaddress,
102*4882a593Smuzhiyun 	&dev_attr_address,
103*4882a593Smuzhiyun 	&dev_attr_atmindex,
104*4882a593Smuzhiyun 	&dev_attr_carrier,
105*4882a593Smuzhiyun 	&dev_attr_type,
106*4882a593Smuzhiyun 	&dev_attr_link_rate,
107*4882a593Smuzhiyun 	NULL
108*4882a593Smuzhiyun };
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun 
atm_uevent(struct device * cdev,struct kobj_uevent_env * env)111*4882a593Smuzhiyun static int atm_uevent(struct device *cdev, struct kobj_uevent_env *env)
112*4882a593Smuzhiyun {
113*4882a593Smuzhiyun 	struct atm_dev *adev;
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun 	if (!cdev)
116*4882a593Smuzhiyun 		return -ENODEV;
117*4882a593Smuzhiyun 
118*4882a593Smuzhiyun 	adev = to_atm_dev(cdev);
119*4882a593Smuzhiyun 	if (!adev)
120*4882a593Smuzhiyun 		return -ENODEV;
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun 	if (add_uevent_var(env, "NAME=%s%d", adev->type, adev->number))
123*4882a593Smuzhiyun 		return -ENOMEM;
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun 	return 0;
126*4882a593Smuzhiyun }
127*4882a593Smuzhiyun 
atm_release(struct device * cdev)128*4882a593Smuzhiyun static void atm_release(struct device *cdev)
129*4882a593Smuzhiyun {
130*4882a593Smuzhiyun 	struct atm_dev *adev = to_atm_dev(cdev);
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun 	kfree(adev);
133*4882a593Smuzhiyun }
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun static struct class atm_class = {
136*4882a593Smuzhiyun 	.name		= "atm",
137*4882a593Smuzhiyun 	.dev_release	= atm_release,
138*4882a593Smuzhiyun 	.dev_uevent		= atm_uevent,
139*4882a593Smuzhiyun };
140*4882a593Smuzhiyun 
atm_register_sysfs(struct atm_dev * adev,struct device * parent)141*4882a593Smuzhiyun int atm_register_sysfs(struct atm_dev *adev, struct device *parent)
142*4882a593Smuzhiyun {
143*4882a593Smuzhiyun 	struct device *cdev = &adev->class_dev;
144*4882a593Smuzhiyun 	int i, j, err;
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun 	cdev->class = &atm_class;
147*4882a593Smuzhiyun 	cdev->parent = parent;
148*4882a593Smuzhiyun 	dev_set_drvdata(cdev, adev);
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun 	dev_set_name(cdev, "%s%d", adev->type, adev->number);
151*4882a593Smuzhiyun 	err = device_register(cdev);
152*4882a593Smuzhiyun 	if (err < 0)
153*4882a593Smuzhiyun 		return err;
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun 	for (i = 0; atm_attrs[i]; i++) {
156*4882a593Smuzhiyun 		err = device_create_file(cdev, atm_attrs[i]);
157*4882a593Smuzhiyun 		if (err)
158*4882a593Smuzhiyun 			goto err_out;
159*4882a593Smuzhiyun 	}
160*4882a593Smuzhiyun 
161*4882a593Smuzhiyun 	return 0;
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun err_out:
164*4882a593Smuzhiyun 	for (j = 0; j < i; j++)
165*4882a593Smuzhiyun 		device_remove_file(cdev, atm_attrs[j]);
166*4882a593Smuzhiyun 	device_del(cdev);
167*4882a593Smuzhiyun 	return err;
168*4882a593Smuzhiyun }
169*4882a593Smuzhiyun 
atm_unregister_sysfs(struct atm_dev * adev)170*4882a593Smuzhiyun void atm_unregister_sysfs(struct atm_dev *adev)
171*4882a593Smuzhiyun {
172*4882a593Smuzhiyun 	struct device *cdev = &adev->class_dev;
173*4882a593Smuzhiyun 
174*4882a593Smuzhiyun 	device_del(cdev);
175*4882a593Smuzhiyun }
176*4882a593Smuzhiyun 
atm_sysfs_init(void)177*4882a593Smuzhiyun int __init atm_sysfs_init(void)
178*4882a593Smuzhiyun {
179*4882a593Smuzhiyun 	return class_register(&atm_class);
180*4882a593Smuzhiyun }
181*4882a593Smuzhiyun 
atm_sysfs_exit(void)182*4882a593Smuzhiyun void __exit atm_sysfs_exit(void)
183*4882a593Smuzhiyun {
184*4882a593Smuzhiyun 	class_unregister(&atm_class);
185*4882a593Smuzhiyun }
186