diff options
author | Reece R. Pollack | 2015-02-24 12:08:52 -0600 |
---|---|---|
committer | Reece R. Pollack | 2015-02-24 12:08:52 -0600 |
commit | b918ff9e61cd10f5e44c0536d638b900a697f471 (patch) | |
tree | 09b66fab06a7cefc3945beddf944830edcca37dc /drivers | |
parent | 6a163422a2f2ef768cbb84b5bfebce7b2e645815 (diff) | |
parent | 7710b4b7519ec0162d18fce7d85f6b22dd07fc7f (diff) | |
download | linux-b918ff9e61cd10f5e44c0536d638b900a697f471.tar.gz linux-b918ff9e61cd10f5e44c0536d638b900a697f471.tar.xz linux-b918ff9e61cd10f5e44c0536d638b900a697f471.zip |
Merge branch 'master/rebuild/24-drivers-net' into master/master
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/ethernet/ti/keystone_qos.c | 127 |
1 files changed, 126 insertions, 1 deletions
diff --git a/drivers/net/ethernet/ti/keystone_qos.c b/drivers/net/ethernet/ti/keystone_qos.c index 18366346865..2a3726cd77e 100644 --- a/drivers/net/ethernet/ti/keystone_qos.c +++ b/drivers/net/ethernet/ti/keystone_qos.c | |||
@@ -41,6 +41,7 @@ struct qos_channel { | |||
41 | const char *tx_chan_name; | 41 | const char *tx_chan_name; |
42 | u32 tx_queue_depth; | 42 | u32 tx_queue_depth; |
43 | struct netcp_tx_pipe tx_pipe; | 43 | struct netcp_tx_pipe tx_pipe; |
44 | struct kobject kobj; | ||
44 | }; | 45 | }; |
45 | 46 | ||
46 | struct qos_device { | 47 | struct qos_device { |
@@ -48,16 +49,104 @@ struct qos_device { | |||
48 | struct device *dev; | 49 | struct device *dev; |
49 | struct device_node *node; | 50 | struct device_node *node; |
50 | u32 multi_if; | 51 | u32 multi_if; |
52 | struct kobject kobj; | ||
51 | }; | 53 | }; |
52 | 54 | ||
53 | struct qos_intf { | 55 | struct qos_intf { |
56 | struct qos_device *qdev; | ||
54 | struct net_device *ndev; | 57 | struct net_device *ndev; |
55 | struct device *dev; | 58 | struct device *dev; |
59 | struct kobject kobj; | ||
56 | int num_channels; | 60 | int num_channels; |
57 | int max_channels; | 61 | int max_channels; |
58 | struct qos_channel channels[1]; | 62 | struct qos_channel channels[1]; |
63 | /* NB: channels is allocated dynamically */ | ||
59 | }; | 64 | }; |
60 | 65 | ||
66 | /* | ||
67 | * Sysfs stuff related to QoS TX Channels | ||
68 | */ | ||
69 | #define kobj_to_qchan(kobj) container_of(kobj, struct qos_channel, kobj) | ||
70 | |||
71 | static ssize_t qos_txchan_show(struct kobject *kobj, | ||
72 | struct kobj_attribute *attr, | ||
73 | char *buf) | ||
74 | { | ||
75 | struct qos_channel *qos_chan = kobj_to_qchan(kobj); | ||
76 | return snprintf(buf, PAGE_SIZE, "%s\n", qos_chan->tx_chan_name); | ||
77 | } | ||
78 | |||
79 | struct kobj_attribute qos_txchan_attr = | ||
80 | __ATTR(tx-channel, S_IRUGO, qos_txchan_show, NULL); | ||
81 | |||
82 | |||
83 | static ssize_t qos_txdepth_show(struct kobject *kobj, | ||
84 | struct kobj_attribute *attr, | ||
85 | char *buf) | ||
86 | { | ||
87 | struct qos_channel *qos_chan = kobj_to_qchan(kobj); | ||
88 | return snprintf(buf, PAGE_SIZE, "%u\n", qos_chan->tx_queue_depth); | ||
89 | } | ||
90 | |||
91 | static ssize_t qos_txdepth_store(struct kobject *kobj, | ||
92 | struct kobj_attribute *attr, | ||
93 | const char *buf, size_t count) | ||
94 | { | ||
95 | struct qos_channel *qos_chan = kobj_to_qchan(kobj); | ||
96 | unsigned int val; | ||
97 | |||
98 | if (kstrtouint(buf, 0, &val) < 0) | ||
99 | return -EINVAL; | ||
100 | |||
101 | qos_chan->tx_queue_depth = val; | ||
102 | |||
103 | return count; | ||
104 | } | ||
105 | |||
106 | struct kobj_attribute qos_txdepth_attr = | ||
107 | __ATTR(tx_queue_depth, S_IRUGO | S_IWUSR, | ||
108 | qos_txdepth_show, qos_txdepth_store); | ||
109 | |||
110 | static struct attribute *qos_txchan_attrs[] = { | ||
111 | &qos_txchan_attr.attr, | ||
112 | &qos_txdepth_attr.attr, | ||
113 | NULL | ||
114 | }; | ||
115 | |||
116 | static struct kobj_type qos_chan_ktype = { | ||
117 | .sysfs_ops = &kobj_sysfs_ops, | ||
118 | .default_attrs = qos_txchan_attrs, | ||
119 | }; | ||
120 | |||
121 | /* Sysfs stuff related to QoS Interfaces */ | ||
122 | static struct kobj_type qos_intf_ktype = { | ||
123 | .sysfs_ops = &kobj_sysfs_ops, | ||
124 | }; | ||
125 | |||
126 | /* Sysfs stuff related to QoS Instances */ | ||
127 | #define kobj_to_qdev(kobj) container_of(kobj, struct qos_device, kobj) | ||
128 | static ssize_t qos_multi_if_show(struct kobject *kobj, | ||
129 | struct kobj_attribute *attr, | ||
130 | char *buf) | ||
131 | { | ||
132 | struct qos_device *qos_dev = kobj_to_qdev(kobj); | ||
133 | return snprintf(buf, PAGE_SIZE, "%u\n", qos_dev->multi_if); | ||
134 | } | ||
135 | |||
136 | struct kobj_attribute qos_multi_if_attr = | ||
137 | __ATTR(multi-interface, S_IRUGO, qos_multi_if_show, NULL); | ||
138 | |||
139 | static struct attribute *qos_inst_attrs[] = { | ||
140 | &qos_multi_if_attr.attr, | ||
141 | NULL | ||
142 | }; | ||
143 | |||
144 | static struct kobj_type qos_inst_ktype = { | ||
145 | .sysfs_ops = &kobj_sysfs_ops, | ||
146 | .default_attrs = qos_inst_attrs, | ||
147 | }; | ||
148 | |||
149 | |||
61 | static int qos_tx_hook(int order, void *data, struct netcp_packet *p_info) | 150 | static int qos_tx_hook(int order, void *data, struct netcp_packet *p_info) |
62 | { | 151 | { |
63 | struct qos_intf *qos_intf = data; | 152 | struct qos_intf *qos_intf = data; |
@@ -148,6 +237,19 @@ static int init_channel(struct qos_intf *qos_intf, | |||
148 | } | 237 | } |
149 | dev_dbg(qos_intf->dev, "tx_queue_depth %u\n", qchan->tx_queue_depth); | 238 | dev_dbg(qos_intf->dev, "tx_queue_depth %u\n", qchan->tx_queue_depth); |
150 | 239 | ||
240 | /* Create the per-channel entry and attributes */ | ||
241 | ret = kobject_init_and_add(&qchan->kobj, &qos_chan_ktype, | ||
242 | kobject_get(&qos_intf->kobj), node->name); | ||
243 | if (ret) { | ||
244 | dev_err(qos_intf->dev, | ||
245 | "failed to create %s/%s/%s sysfs entry\n", | ||
246 | qos_intf->qdev->kobj.name, qos_intf->kobj.name, | ||
247 | node->name); | ||
248 | kobject_put(&qchan->kobj); | ||
249 | kobject_put(&qos_intf->kobj); | ||
250 | return ret; | ||
251 | } | ||
252 | |||
151 | return 0; | 253 | return 0; |
152 | } | 254 | } |
153 | 255 | ||
@@ -173,6 +275,7 @@ static int qos_attach(void *inst_priv, struct net_device *ndev, | |||
173 | } | 275 | } |
174 | qos_intf->max_channels = max_channels; | 276 | qos_intf->max_channels = max_channels; |
175 | 277 | ||
278 | qos_intf->qdev = qos_dev; | ||
176 | qos_intf->ndev = ndev; | 279 | qos_intf->ndev = ndev; |
177 | qos_intf->dev = qos_dev->dev; | 280 | qos_intf->dev = qos_dev->dev; |
178 | 281 | ||
@@ -190,6 +293,17 @@ static int qos_attach(void *inst_priv, struct net_device *ndev, | |||
190 | goto exit; | 293 | goto exit; |
191 | } | 294 | } |
192 | 295 | ||
296 | /* Create the per-interface sysfs entry */ | ||
297 | ret = kobject_init_and_add(&qos_intf->kobj, &qos_intf_ktype, | ||
298 | kobject_get(&qos_intf->qdev->kobj), node_name); | ||
299 | if (ret) { | ||
300 | dev_err(qos_intf->dev, "failed to create %s/%s sysfs entry\n", | ||
301 | qos_intf->qdev->kobj.name, node_name); | ||
302 | kobject_put(&qos_intf->kobj); | ||
303 | kobject_put(&qos_intf->qdev->kobj); | ||
304 | goto exit; | ||
305 | } | ||
306 | |||
193 | qos_intf->num_channels = 0; | 307 | qos_intf->num_channels = 0; |
194 | for_each_child_of_node(interface, channel) { | 308 | for_each_child_of_node(interface, channel) { |
195 | if (qos_intf->num_channels >= max_channels) { | 309 | if (qos_intf->num_channels >= max_channels) { |
@@ -245,7 +359,7 @@ static int qos_probe(struct netcp_device *netcp_device, | |||
245 | { | 359 | { |
246 | struct qos_device *qos_dev; | 360 | struct qos_device *qos_dev; |
247 | int ret = 0; | 361 | int ret = 0; |
248 | 362 | ||
249 | qos_dev = devm_kzalloc(dev, sizeof(struct qos_device), GFP_KERNEL); | 363 | qos_dev = devm_kzalloc(dev, sizeof(struct qos_device), GFP_KERNEL); |
250 | if (!qos_dev) { | 364 | if (!qos_dev) { |
251 | dev_err(dev, "memory allocation failed\n"); | 365 | dev_err(dev, "memory allocation failed\n"); |
@@ -266,6 +380,17 @@ static int qos_probe(struct netcp_device *netcp_device, | |||
266 | if (of_find_property(node, "multi-interface", NULL)) | 380 | if (of_find_property(node, "multi-interface", NULL)) |
267 | qos_dev->multi_if = 1; | 381 | qos_dev->multi_if = 1; |
268 | 382 | ||
383 | /* Create the per-instance sysfs entry */ | ||
384 | ret = kobject_init_and_add(&qos_dev->kobj, &qos_inst_ktype, | ||
385 | kobject_get(&dev->kobj), node->name); | ||
386 | if (ret) { | ||
387 | dev_err(dev, "failed to create %s sysfs entry\n", | ||
388 | node->name); | ||
389 | kobject_put(&qos_dev->kobj); | ||
390 | kobject_put(&dev->kobj); | ||
391 | goto exit; | ||
392 | } | ||
393 | |||
269 | return 0; | 394 | return 0; |
270 | 395 | ||
271 | exit: | 396 | exit: |