Merge tag 'powerpc-4.8-6' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc...
[cascardo/linux.git] / drivers / net / ethernet / cavium / thunder / nicvf_ethtool.c
1 /*
2  * Copyright (C) 2015 Cavium, Inc.
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of version 2 of the GNU General Public License
6  * as published by the Free Software Foundation.
7  */
8
9 /* ETHTOOL Support for VNIC_VF Device*/
10
11 #include <linux/pci.h>
12
13 #include "nic_reg.h"
14 #include "nic.h"
15 #include "nicvf_queues.h"
16 #include "q_struct.h"
17 #include "thunder_bgx.h"
18
19 #define DRV_NAME        "thunder-nicvf"
20 #define DRV_VERSION     "1.0"
21
22 struct nicvf_stat {
23         char name[ETH_GSTRING_LEN];
24         unsigned int index;
25 };
26
27 #define NICVF_HW_STAT(stat) { \
28         .name = #stat, \
29         .index = offsetof(struct nicvf_hw_stats, stat) / sizeof(u64), \
30 }
31
32 #define NICVF_DRV_STAT(stat) { \
33         .name = #stat, \
34         .index = offsetof(struct nicvf_drv_stats, stat) / sizeof(u64), \
35 }
36
37 static const struct nicvf_stat nicvf_hw_stats[] = {
38         NICVF_HW_STAT(rx_bytes),
39         NICVF_HW_STAT(rx_ucast_frames),
40         NICVF_HW_STAT(rx_bcast_frames),
41         NICVF_HW_STAT(rx_mcast_frames),
42         NICVF_HW_STAT(rx_fcs_errors),
43         NICVF_HW_STAT(rx_l2_errors),
44         NICVF_HW_STAT(rx_drop_red),
45         NICVF_HW_STAT(rx_drop_red_bytes),
46         NICVF_HW_STAT(rx_drop_overrun),
47         NICVF_HW_STAT(rx_drop_overrun_bytes),
48         NICVF_HW_STAT(rx_drop_bcast),
49         NICVF_HW_STAT(rx_drop_mcast),
50         NICVF_HW_STAT(rx_drop_l3_bcast),
51         NICVF_HW_STAT(rx_drop_l3_mcast),
52         NICVF_HW_STAT(rx_bgx_truncated_pkts),
53         NICVF_HW_STAT(rx_jabber_errs),
54         NICVF_HW_STAT(rx_fcs_errs),
55         NICVF_HW_STAT(rx_bgx_errs),
56         NICVF_HW_STAT(rx_prel2_errs),
57         NICVF_HW_STAT(rx_l2_hdr_malformed),
58         NICVF_HW_STAT(rx_oversize),
59         NICVF_HW_STAT(rx_undersize),
60         NICVF_HW_STAT(rx_l2_len_mismatch),
61         NICVF_HW_STAT(rx_l2_pclp),
62         NICVF_HW_STAT(rx_ip_ver_errs),
63         NICVF_HW_STAT(rx_ip_csum_errs),
64         NICVF_HW_STAT(rx_ip_hdr_malformed),
65         NICVF_HW_STAT(rx_ip_payload_malformed),
66         NICVF_HW_STAT(rx_ip_ttl_errs),
67         NICVF_HW_STAT(rx_l3_pclp),
68         NICVF_HW_STAT(rx_l4_malformed),
69         NICVF_HW_STAT(rx_l4_csum_errs),
70         NICVF_HW_STAT(rx_udp_len_errs),
71         NICVF_HW_STAT(rx_l4_port_errs),
72         NICVF_HW_STAT(rx_tcp_flag_errs),
73         NICVF_HW_STAT(rx_tcp_offset_errs),
74         NICVF_HW_STAT(rx_l4_pclp),
75         NICVF_HW_STAT(rx_truncated_pkts),
76         NICVF_HW_STAT(tx_bytes_ok),
77         NICVF_HW_STAT(tx_ucast_frames_ok),
78         NICVF_HW_STAT(tx_bcast_frames_ok),
79         NICVF_HW_STAT(tx_mcast_frames_ok),
80 };
81
82 static const struct nicvf_stat nicvf_drv_stats[] = {
83         NICVF_DRV_STAT(rx_frames_ok),
84         NICVF_DRV_STAT(rx_frames_64),
85         NICVF_DRV_STAT(rx_frames_127),
86         NICVF_DRV_STAT(rx_frames_255),
87         NICVF_DRV_STAT(rx_frames_511),
88         NICVF_DRV_STAT(rx_frames_1023),
89         NICVF_DRV_STAT(rx_frames_1518),
90         NICVF_DRV_STAT(rx_frames_jumbo),
91         NICVF_DRV_STAT(rx_drops),
92         NICVF_DRV_STAT(rcv_buffer_alloc_failures),
93         NICVF_DRV_STAT(tx_frames_ok),
94         NICVF_DRV_STAT(tx_tso),
95         NICVF_DRV_STAT(tx_drops),
96         NICVF_DRV_STAT(tx_timeout),
97         NICVF_DRV_STAT(txq_stop),
98         NICVF_DRV_STAT(txq_wake),
99 };
100
101 static const struct nicvf_stat nicvf_queue_stats[] = {
102         { "bytes", 0 },
103         { "frames", 1 },
104 };
105
106 static const unsigned int nicvf_n_hw_stats = ARRAY_SIZE(nicvf_hw_stats);
107 static const unsigned int nicvf_n_drv_stats = ARRAY_SIZE(nicvf_drv_stats);
108 static const unsigned int nicvf_n_queue_stats = ARRAY_SIZE(nicvf_queue_stats);
109
110 static int nicvf_get_settings(struct net_device *netdev,
111                               struct ethtool_cmd *cmd)
112 {
113         struct nicvf *nic = netdev_priv(netdev);
114
115         cmd->supported = 0;
116         cmd->transceiver = XCVR_EXTERNAL;
117
118         if (!nic->link_up) {
119                 cmd->duplex = DUPLEX_UNKNOWN;
120                 ethtool_cmd_speed_set(cmd, SPEED_UNKNOWN);
121                 return 0;
122         }
123
124         if (nic->speed <= 1000) {
125                 cmd->port = PORT_MII;
126                 cmd->autoneg = AUTONEG_ENABLE;
127         } else {
128                 cmd->port = PORT_FIBRE;
129                 cmd->autoneg = AUTONEG_DISABLE;
130         }
131         cmd->duplex = nic->duplex;
132         ethtool_cmd_speed_set(cmd, nic->speed);
133
134         return 0;
135 }
136
137 static u32 nicvf_get_link(struct net_device *netdev)
138 {
139         struct nicvf *nic = netdev_priv(netdev);
140
141         return nic->link_up;
142 }
143
144 static void nicvf_get_drvinfo(struct net_device *netdev,
145                               struct ethtool_drvinfo *info)
146 {
147         struct nicvf *nic = netdev_priv(netdev);
148
149         strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
150         strlcpy(info->version, DRV_VERSION, sizeof(info->version));
151         strlcpy(info->bus_info, pci_name(nic->pdev), sizeof(info->bus_info));
152 }
153
154 static u32 nicvf_get_msglevel(struct net_device *netdev)
155 {
156         struct nicvf *nic = netdev_priv(netdev);
157
158         return nic->msg_enable;
159 }
160
161 static void nicvf_set_msglevel(struct net_device *netdev, u32 lvl)
162 {
163         struct nicvf *nic = netdev_priv(netdev);
164
165         nic->msg_enable = lvl;
166 }
167
168 static void nicvf_get_qset_strings(struct nicvf *nic, u8 **data, int qset)
169 {
170         int stats, qidx;
171         int start_qidx = qset * MAX_RCV_QUEUES_PER_QS;
172
173         for (qidx = 0; qidx < nic->qs->rq_cnt; qidx++) {
174                 for (stats = 0; stats < nicvf_n_queue_stats; stats++) {
175                         sprintf(*data, "rxq%d: %s", qidx + start_qidx,
176                                 nicvf_queue_stats[stats].name);
177                         *data += ETH_GSTRING_LEN;
178                 }
179         }
180
181         for (qidx = 0; qidx < nic->qs->sq_cnt; qidx++) {
182                 for (stats = 0; stats < nicvf_n_queue_stats; stats++) {
183                         sprintf(*data, "txq%d: %s", qidx + start_qidx,
184                                 nicvf_queue_stats[stats].name);
185                         *data += ETH_GSTRING_LEN;
186                 }
187         }
188 }
189
190 static void nicvf_get_strings(struct net_device *netdev, u32 sset, u8 *data)
191 {
192         struct nicvf *nic = netdev_priv(netdev);
193         int stats;
194         int sqs;
195
196         if (sset != ETH_SS_STATS)
197                 return;
198
199         for (stats = 0; stats < nicvf_n_hw_stats; stats++) {
200                 memcpy(data, nicvf_hw_stats[stats].name, ETH_GSTRING_LEN);
201                 data += ETH_GSTRING_LEN;
202         }
203
204         for (stats = 0; stats < nicvf_n_drv_stats; stats++) {
205                 memcpy(data, nicvf_drv_stats[stats].name, ETH_GSTRING_LEN);
206                 data += ETH_GSTRING_LEN;
207         }
208
209         nicvf_get_qset_strings(nic, &data, 0);
210
211         for (sqs = 0; sqs < nic->sqs_count; sqs++) {
212                 if (!nic->snicvf[sqs])
213                         continue;
214                 nicvf_get_qset_strings(nic->snicvf[sqs], &data, sqs + 1);
215         }
216
217         for (stats = 0; stats < BGX_RX_STATS_COUNT; stats++) {
218                 sprintf(data, "bgx_rxstat%d: ", stats);
219                 data += ETH_GSTRING_LEN;
220         }
221
222         for (stats = 0; stats < BGX_TX_STATS_COUNT; stats++) {
223                 sprintf(data, "bgx_txstat%d: ", stats);
224                 data += ETH_GSTRING_LEN;
225         }
226 }
227
228 static int nicvf_get_sset_count(struct net_device *netdev, int sset)
229 {
230         struct nicvf *nic = netdev_priv(netdev);
231         int qstats_count;
232         int sqs;
233
234         if (sset != ETH_SS_STATS)
235                 return -EINVAL;
236
237         qstats_count = nicvf_n_queue_stats *
238                        (nic->qs->rq_cnt + nic->qs->sq_cnt);
239         for (sqs = 0; sqs < nic->sqs_count; sqs++) {
240                 struct nicvf *snic;
241
242                 snic = nic->snicvf[sqs];
243                 if (!snic)
244                         continue;
245                 qstats_count += nicvf_n_queue_stats *
246                                 (snic->qs->rq_cnt + snic->qs->sq_cnt);
247         }
248
249         return nicvf_n_hw_stats + nicvf_n_drv_stats +
250                 qstats_count +
251                 BGX_RX_STATS_COUNT + BGX_TX_STATS_COUNT;
252 }
253
254 static void nicvf_get_qset_stats(struct nicvf *nic,
255                                  struct ethtool_stats *stats, u64 **data)
256 {
257         int stat, qidx;
258
259         if (!nic)
260                 return;
261
262         for (qidx = 0; qidx < nic->qs->rq_cnt; qidx++) {
263                 nicvf_update_rq_stats(nic, qidx);
264                 for (stat = 0; stat < nicvf_n_queue_stats; stat++)
265                         *((*data)++) = ((u64 *)&nic->qs->rq[qidx].stats)
266                                         [nicvf_queue_stats[stat].index];
267         }
268
269         for (qidx = 0; qidx < nic->qs->sq_cnt; qidx++) {
270                 nicvf_update_sq_stats(nic, qidx);
271                 for (stat = 0; stat < nicvf_n_queue_stats; stat++)
272                         *((*data)++) = ((u64 *)&nic->qs->sq[qidx].stats)
273                                         [nicvf_queue_stats[stat].index];
274         }
275 }
276
277 static void nicvf_get_ethtool_stats(struct net_device *netdev,
278                                     struct ethtool_stats *stats, u64 *data)
279 {
280         struct nicvf *nic = netdev_priv(netdev);
281         int stat;
282         int sqs;
283
284         nicvf_update_stats(nic);
285
286         /* Update LMAC stats */
287         nicvf_update_lmac_stats(nic);
288
289         for (stat = 0; stat < nicvf_n_hw_stats; stat++)
290                 *(data++) = ((u64 *)&nic->hw_stats)
291                                 [nicvf_hw_stats[stat].index];
292         for (stat = 0; stat < nicvf_n_drv_stats; stat++)
293                 *(data++) = ((u64 *)&nic->drv_stats)
294                                 [nicvf_drv_stats[stat].index];
295
296         nicvf_get_qset_stats(nic, stats, &data);
297
298         for (sqs = 0; sqs < nic->sqs_count; sqs++) {
299                 if (!nic->snicvf[sqs])
300                         continue;
301                 nicvf_get_qset_stats(nic->snicvf[sqs], stats, &data);
302         }
303
304         for (stat = 0; stat < BGX_RX_STATS_COUNT; stat++)
305                 *(data++) = nic->bgx_stats.rx_stats[stat];
306         for (stat = 0; stat < BGX_TX_STATS_COUNT; stat++)
307                 *(data++) = nic->bgx_stats.tx_stats[stat];
308 }
309
310 static int nicvf_get_regs_len(struct net_device *dev)
311 {
312         return sizeof(u64) * NIC_VF_REG_COUNT;
313 }
314
315 static void nicvf_get_regs(struct net_device *dev,
316                            struct ethtool_regs *regs, void *reg)
317 {
318         struct nicvf *nic = netdev_priv(dev);
319         u64 *p = (u64 *)reg;
320         u64 reg_offset;
321         int mbox, key, stat, q;
322         int i = 0;
323
324         regs->version = 0;
325         memset(p, 0, NIC_VF_REG_COUNT);
326
327         p[i++] = nicvf_reg_read(nic, NIC_VNIC_CFG);
328         /* Mailbox registers */
329         for (mbox = 0; mbox < NIC_PF_VF_MAILBOX_SIZE; mbox++)
330                 p[i++] = nicvf_reg_read(nic,
331                                         NIC_VF_PF_MAILBOX_0_1 | (mbox << 3));
332
333         p[i++] = nicvf_reg_read(nic, NIC_VF_INT);
334         p[i++] = nicvf_reg_read(nic, NIC_VF_INT_W1S);
335         p[i++] = nicvf_reg_read(nic, NIC_VF_ENA_W1C);
336         p[i++] = nicvf_reg_read(nic, NIC_VF_ENA_W1S);
337         p[i++] = nicvf_reg_read(nic, NIC_VNIC_RSS_CFG);
338
339         for (key = 0; key < RSS_HASH_KEY_SIZE; key++)
340                 p[i++] = nicvf_reg_read(nic, NIC_VNIC_RSS_KEY_0_4 | (key << 3));
341
342         /* Tx/Rx statistics */
343         for (stat = 0; stat < TX_STATS_ENUM_LAST; stat++)
344                 p[i++] = nicvf_reg_read(nic,
345                                         NIC_VNIC_TX_STAT_0_4 | (stat << 3));
346
347         for (i = 0; i < RX_STATS_ENUM_LAST; i++)
348                 p[i++] = nicvf_reg_read(nic,
349                                         NIC_VNIC_RX_STAT_0_13 | (stat << 3));
350
351         p[i++] = nicvf_reg_read(nic, NIC_QSET_RQ_GEN_CFG);
352
353         /* All completion queue's registers */
354         for (q = 0; q < MAX_CMP_QUEUES_PER_QS; q++) {
355                 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_CQ_0_7_CFG, q);
356                 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_CQ_0_7_CFG2, q);
357                 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_CQ_0_7_THRESH, q);
358                 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_CQ_0_7_BASE, q);
359                 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_CQ_0_7_HEAD, q);
360                 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_CQ_0_7_TAIL, q);
361                 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_CQ_0_7_DOOR, q);
362                 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_CQ_0_7_STATUS, q);
363                 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_CQ_0_7_STATUS2, q);
364                 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_CQ_0_7_DEBUG, q);
365         }
366
367         /* All receive queue's registers */
368         for (q = 0; q < MAX_RCV_QUEUES_PER_QS; q++) {
369                 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_RQ_0_7_CFG, q);
370                 p[i++] = nicvf_queue_reg_read(nic,
371                                                   NIC_QSET_RQ_0_7_STAT_0_1, q);
372                 reg_offset = NIC_QSET_RQ_0_7_STAT_0_1 | (1 << 3);
373                 p[i++] = nicvf_queue_reg_read(nic, reg_offset, q);
374         }
375
376         for (q = 0; q < MAX_SND_QUEUES_PER_QS; q++) {
377                 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_CFG, q);
378                 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_THRESH, q);
379                 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_BASE, q);
380                 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_HEAD, q);
381                 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_TAIL, q);
382                 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_DOOR, q);
383                 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_STATUS, q);
384                 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_DEBUG, q);
385                 /* Padding, was NIC_QSET_SQ_0_7_CNM_CHG, which
386                  * produces bus errors when read
387                  */
388                 p[i++] = 0;
389                 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_STAT_0_1, q);
390                 reg_offset = NIC_QSET_SQ_0_7_STAT_0_1 | (1 << 3);
391                 p[i++] = nicvf_queue_reg_read(nic, reg_offset, q);
392         }
393
394         for (q = 0; q < MAX_RCV_BUF_DESC_RINGS_PER_QS; q++) {
395                 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_RBDR_0_1_CFG, q);
396                 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_RBDR_0_1_THRESH, q);
397                 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_RBDR_0_1_BASE, q);
398                 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_RBDR_0_1_HEAD, q);
399                 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_RBDR_0_1_TAIL, q);
400                 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_RBDR_0_1_DOOR, q);
401                 p[i++] = nicvf_queue_reg_read(nic,
402                                               NIC_QSET_RBDR_0_1_STATUS0, q);
403                 p[i++] = nicvf_queue_reg_read(nic,
404                                               NIC_QSET_RBDR_0_1_STATUS1, q);
405                 reg_offset = NIC_QSET_RBDR_0_1_PREFETCH_STATUS;
406                 p[i++] = nicvf_queue_reg_read(nic, reg_offset, q);
407         }
408 }
409
410 static int nicvf_get_coalesce(struct net_device *netdev,
411                               struct ethtool_coalesce *cmd)
412 {
413         struct nicvf *nic = netdev_priv(netdev);
414
415         cmd->rx_coalesce_usecs = nic->cq_coalesce_usecs;
416         return 0;
417 }
418
419 static void nicvf_get_ringparam(struct net_device *netdev,
420                                 struct ethtool_ringparam *ring)
421 {
422         struct nicvf *nic = netdev_priv(netdev);
423         struct queue_set *qs = nic->qs;
424
425         ring->rx_max_pending = MAX_RCV_BUF_COUNT;
426         ring->rx_pending = qs->rbdr_len;
427         ring->tx_max_pending = MAX_SND_QUEUE_LEN;
428         ring->tx_pending = qs->sq_len;
429 }
430
431 static int nicvf_get_rss_hash_opts(struct nicvf *nic,
432                                    struct ethtool_rxnfc *info)
433 {
434         info->data = 0;
435
436         switch (info->flow_type) {
437         case TCP_V4_FLOW:
438         case TCP_V6_FLOW:
439         case UDP_V4_FLOW:
440         case UDP_V6_FLOW:
441         case SCTP_V4_FLOW:
442         case SCTP_V6_FLOW:
443                 info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
444         case IPV4_FLOW:
445         case IPV6_FLOW:
446                 info->data |= RXH_IP_SRC | RXH_IP_DST;
447                 break;
448         default:
449                 return -EINVAL;
450         }
451
452         return 0;
453 }
454
455 static int nicvf_get_rxnfc(struct net_device *dev,
456                            struct ethtool_rxnfc *info, u32 *rules)
457 {
458         struct nicvf *nic = netdev_priv(dev);
459         int ret = -EOPNOTSUPP;
460
461         switch (info->cmd) {
462         case ETHTOOL_GRXRINGS:
463                 info->data = nic->rx_queues;
464                 ret = 0;
465                 break;
466         case ETHTOOL_GRXFH:
467                 return nicvf_get_rss_hash_opts(nic, info);
468         default:
469                 break;
470         }
471         return ret;
472 }
473
474 static int nicvf_set_rss_hash_opts(struct nicvf *nic,
475                                    struct ethtool_rxnfc *info)
476 {
477         struct nicvf_rss_info *rss = &nic->rss_info;
478         u64 rss_cfg = nicvf_reg_read(nic, NIC_VNIC_RSS_CFG);
479
480         if (!rss->enable)
481                 netdev_err(nic->netdev,
482                            "RSS is disabled, hash cannot be set\n");
483
484         netdev_info(nic->netdev, "Set RSS flow type = %d, data = %lld\n",
485                     info->flow_type, info->data);
486
487         if (!(info->data & RXH_IP_SRC) || !(info->data & RXH_IP_DST))
488                 return -EINVAL;
489
490         switch (info->flow_type) {
491         case TCP_V4_FLOW:
492         case TCP_V6_FLOW:
493                 switch (info->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
494                 case 0:
495                         rss_cfg &= ~(1ULL << RSS_HASH_TCP);
496                         break;
497                 case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
498                         rss_cfg |= (1ULL << RSS_HASH_TCP);
499                         break;
500                 default:
501                         return -EINVAL;
502                 }
503                 break;
504         case UDP_V4_FLOW:
505         case UDP_V6_FLOW:
506                 switch (info->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
507                 case 0:
508                         rss_cfg &= ~(1ULL << RSS_HASH_UDP);
509                         break;
510                 case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
511                         rss_cfg |= (1ULL << RSS_HASH_UDP);
512                         break;
513                 default:
514                         return -EINVAL;
515                 }
516                 break;
517         case SCTP_V4_FLOW:
518         case SCTP_V6_FLOW:
519                 switch (info->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
520                 case 0:
521                         rss_cfg &= ~(1ULL << RSS_HASH_L4ETC);
522                         break;
523                 case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
524                         rss_cfg |= (1ULL << RSS_HASH_L4ETC);
525                         break;
526                 default:
527                         return -EINVAL;
528                 }
529                 break;
530         case IPV4_FLOW:
531         case IPV6_FLOW:
532                 rss_cfg = RSS_HASH_IP;
533                 break;
534         default:
535                 return -EINVAL;
536         }
537
538         nicvf_reg_write(nic, NIC_VNIC_RSS_CFG, rss_cfg);
539         return 0;
540 }
541
542 static int nicvf_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info)
543 {
544         struct nicvf *nic = netdev_priv(dev);
545
546         switch (info->cmd) {
547         case ETHTOOL_SRXFH:
548                 return nicvf_set_rss_hash_opts(nic, info);
549         default:
550                 break;
551         }
552         return -EOPNOTSUPP;
553 }
554
555 static u32 nicvf_get_rxfh_key_size(struct net_device *netdev)
556 {
557         return RSS_HASH_KEY_SIZE * sizeof(u64);
558 }
559
560 static u32 nicvf_get_rxfh_indir_size(struct net_device *dev)
561 {
562         struct nicvf *nic = netdev_priv(dev);
563
564         return nic->rss_info.rss_size;
565 }
566
567 static int nicvf_get_rxfh(struct net_device *dev, u32 *indir, u8 *hkey,
568                           u8 *hfunc)
569 {
570         struct nicvf *nic = netdev_priv(dev);
571         struct nicvf_rss_info *rss = &nic->rss_info;
572         int idx;
573
574         if (indir) {
575                 for (idx = 0; idx < rss->rss_size; idx++)
576                         indir[idx] = rss->ind_tbl[idx];
577         }
578
579         if (hkey)
580                 memcpy(hkey, rss->key, RSS_HASH_KEY_SIZE * sizeof(u64));
581
582         if (hfunc)
583                 *hfunc = ETH_RSS_HASH_TOP;
584
585         return 0;
586 }
587
588 static int nicvf_set_rxfh(struct net_device *dev, const u32 *indir,
589                           const u8 *hkey, u8 hfunc)
590 {
591         struct nicvf *nic = netdev_priv(dev);
592         struct nicvf_rss_info *rss = &nic->rss_info;
593         int idx;
594
595         if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
596                 return -EOPNOTSUPP;
597
598         if (!rss->enable) {
599                 netdev_err(nic->netdev,
600                            "RSS is disabled, cannot change settings\n");
601                 return -EIO;
602         }
603
604         if (indir) {
605                 for (idx = 0; idx < rss->rss_size; idx++)
606                         rss->ind_tbl[idx] = indir[idx];
607         }
608
609         if (hkey) {
610                 memcpy(rss->key, hkey, RSS_HASH_KEY_SIZE * sizeof(u64));
611                 nicvf_set_rss_key(nic);
612         }
613
614         nicvf_config_rss(nic);
615         return 0;
616 }
617
618 /* Get no of queues device supports and current queue count */
619 static void nicvf_get_channels(struct net_device *dev,
620                                struct ethtool_channels *channel)
621 {
622         struct nicvf *nic = netdev_priv(dev);
623
624         memset(channel, 0, sizeof(*channel));
625
626         channel->max_rx = nic->max_queues;
627         channel->max_tx = nic->max_queues;
628
629         channel->rx_count = nic->rx_queues;
630         channel->tx_count = nic->tx_queues;
631 }
632
633 /* Set no of Tx, Rx queues to be used */
634 static int nicvf_set_channels(struct net_device *dev,
635                               struct ethtool_channels *channel)
636 {
637         struct nicvf *nic = netdev_priv(dev);
638         int err = 0;
639         bool if_up = netif_running(dev);
640         int cqcount;
641
642         if (!channel->rx_count || !channel->tx_count)
643                 return -EINVAL;
644         if (channel->rx_count > nic->max_queues)
645                 return -EINVAL;
646         if (channel->tx_count > nic->max_queues)
647                 return -EINVAL;
648
649         if (if_up)
650                 nicvf_stop(dev);
651
652         cqcount = max(channel->rx_count, channel->tx_count);
653
654         if (cqcount > MAX_CMP_QUEUES_PER_QS) {
655                 nic->sqs_count = roundup(cqcount, MAX_CMP_QUEUES_PER_QS);
656                 nic->sqs_count = (nic->sqs_count / MAX_CMP_QUEUES_PER_QS) - 1;
657         } else {
658                 nic->sqs_count = 0;
659         }
660
661         nic->qs->rq_cnt = min_t(u32, channel->rx_count, MAX_RCV_QUEUES_PER_QS);
662         nic->qs->sq_cnt = min_t(u32, channel->tx_count, MAX_SND_QUEUES_PER_QS);
663         nic->qs->cq_cnt = max(nic->qs->rq_cnt, nic->qs->sq_cnt);
664
665         nic->rx_queues = channel->rx_count;
666         nic->tx_queues = channel->tx_count;
667         err = nicvf_set_real_num_queues(dev, nic->tx_queues, nic->rx_queues);
668         if (err)
669                 return err;
670
671         if (if_up)
672                 nicvf_open(dev);
673
674         netdev_info(dev, "Setting num Tx rings to %d, Rx rings to %d success\n",
675                     nic->tx_queues, nic->rx_queues);
676
677         return err;
678 }
679
680 static const struct ethtool_ops nicvf_ethtool_ops = {
681         .get_settings           = nicvf_get_settings,
682         .get_link               = nicvf_get_link,
683         .get_drvinfo            = nicvf_get_drvinfo,
684         .get_msglevel           = nicvf_get_msglevel,
685         .set_msglevel           = nicvf_set_msglevel,
686         .get_strings            = nicvf_get_strings,
687         .get_sset_count         = nicvf_get_sset_count,
688         .get_ethtool_stats      = nicvf_get_ethtool_stats,
689         .get_regs_len           = nicvf_get_regs_len,
690         .get_regs               = nicvf_get_regs,
691         .get_coalesce           = nicvf_get_coalesce,
692         .get_ringparam          = nicvf_get_ringparam,
693         .get_rxnfc              = nicvf_get_rxnfc,
694         .set_rxnfc              = nicvf_set_rxnfc,
695         .get_rxfh_key_size      = nicvf_get_rxfh_key_size,
696         .get_rxfh_indir_size    = nicvf_get_rxfh_indir_size,
697         .get_rxfh               = nicvf_get_rxfh,
698         .set_rxfh               = nicvf_set_rxfh,
699         .get_channels           = nicvf_get_channels,
700         .set_channels           = nicvf_set_channels,
701         .get_ts_info            = ethtool_op_get_ts_info,
702 };
703
704 void nicvf_set_ethtool_ops(struct net_device *netdev)
705 {
706         netdev->ethtool_ops = &nicvf_ethtool_ops;
707 }