aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorReece R. Pollack2015-02-24 12:08:52 -0600
committerReece R. Pollack2015-02-24 12:08:52 -0600
commitb918ff9e61cd10f5e44c0536d638b900a697f471 (patch)
tree09b66fab06a7cefc3945beddf944830edcca37dc
parent6a163422a2f2ef768cbb84b5bfebce7b2e645815 (diff)
parent7710b4b7519ec0162d18fce7d85f6b22dd07fc7f (diff)
downloadlinux-b918ff9e61cd10f5e44c0536d638b900a697f471.tar.gz
linux-b918ff9e61cd10f5e44c0536d638b900a697f471.tar.xz
linux-b918ff9e61cd10f5e44c0536d638b900a697f471.zip
Merge branch 'master/rebuild/24-drivers-net' into master/master
-rw-r--r--drivers/net/ethernet/ti/keystone_qos.c127
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
46struct qos_device { 47struct 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
53struct qos_intf { 55struct 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
71static 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
79struct kobj_attribute qos_txchan_attr =
80 __ATTR(tx-channel, S_IRUGO, qos_txchan_show, NULL);
81
82
83static 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
91static 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
106struct kobj_attribute qos_txdepth_attr =
107 __ATTR(tx_queue_depth, S_IRUGO | S_IWUSR,
108 qos_txdepth_show, qos_txdepth_store);
109
110static struct attribute *qos_txchan_attrs[] = {
111 &qos_txchan_attr.attr,
112 &qos_txdepth_attr.attr,
113 NULL
114};
115
116static 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 */
122static 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)
128static 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
136struct kobj_attribute qos_multi_if_attr =
137 __ATTR(multi-interface, S_IRUGO, qos_multi_if_show, NULL);
138
139static struct attribute *qos_inst_attrs[] = {
140 &qos_multi_if_attr.attr,
141 NULL
142};
143
144static struct kobj_type qos_inst_ktype = {
145 .sysfs_ops = &kobj_sysfs_ops,
146 .default_attrs = qos_inst_attrs,
147};
148
149
61static int qos_tx_hook(int order, void *data, struct netcp_packet *p_info) 150static 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
271exit: 396exit: