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