forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c
....@@ -1,18 +1,6 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (C) 2013-2015 Chelsio Communications. All rights reserved.
3
- *
4
- * This program is free software; you can redistribute it and/or modify it
5
- * under the terms and conditions of the GNU General Public License,
6
- * version 2, as published by the Free Software Foundation.
7
- *
8
- * This program is distributed in the hope it will be useful, but WITHOUT
9
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11
- * more details.
12
- *
13
- * The full GNU General Public License is included in this distribution in
14
- * the file called "COPYING".
15
- *
164 */
175
186 #include <linux/firmware.h>
....@@ -22,6 +10,8 @@
2210 #include "t4_regs.h"
2311 #include "t4fw_api.h"
2412 #include "cxgb4_cudbg.h"
13
+#include "cxgb4_filter.h"
14
+#include "cxgb4_tc_flower.h"
2515
2616 #define EEPROM_MAGIC 0x38E2F10C
2717
....@@ -34,6 +24,23 @@
3424 {
3525 netdev2adap(dev)->msg_enable = val;
3626 }
27
+
28
+enum cxgb4_ethtool_tests {
29
+ CXGB4_ETHTOOL_LB_TEST,
30
+ CXGB4_ETHTOOL_MAX_TEST,
31
+};
32
+
33
+static const char cxgb4_selftest_strings[CXGB4_ETHTOOL_MAX_TEST][ETH_GSTRING_LEN] = {
34
+ "Loop back test (offline)",
35
+};
36
+
37
+static const char * const flash_region_strings[] = {
38
+ "All",
39
+ "Firmware",
40
+ "PHY Firmware",
41
+ "Boot",
42
+ "Boot CFG",
43
+};
3744
3845 static const char stats_strings[][ETH_GSTRING_LEN] = {
3946 "tx_octets_ok ",
....@@ -103,12 +110,22 @@
103110 "rx_bg3_frames_trunc ",
104111
105112 "tso ",
113
+ "uso ",
106114 "tx_csum_offload ",
107115 "rx_csum_good ",
108116 "vlan_extractions ",
109117 "vlan_insertions ",
110118 "gro_packets ",
111119 "gro_merged ",
120
+#if IS_ENABLED(CONFIG_CHELSIO_TLS_DEVICE)
121
+ "tx_tls_encrypted_packets",
122
+ "tx_tls_encrypted_bytes ",
123
+ "tx_tls_ctx ",
124
+ "tx_tls_ooo ",
125
+ "tx_tls_skip_no_sync_data",
126
+ "tx_tls_drop_no_sync_data",
127
+ "tx_tls_drop_bypass_req ",
128
+#endif
112129 };
113130
114131 static char adapter_stats_strings[][ETH_GSTRING_LEN] = {
....@@ -158,6 +175,8 @@
158175 ARRAY_SIZE(loopback_stats_strings);
159176 case ETH_SS_PRIV_FLAGS:
160177 return ARRAY_SIZE(cxgb4_priv_flags_strings);
178
+ case ETH_SS_TEST:
179
+ return ARRAY_SIZE(cxgb4_selftest_strings);
161180 default:
162181 return -EOPNOTSUPP;
163182 }
....@@ -181,15 +200,11 @@
181200 u32 exprom_vers;
182201
183202 strlcpy(info->driver, cxgb4_driver_name, sizeof(info->driver));
184
- strlcpy(info->version, cxgb4_driver_version,
185
- sizeof(info->version));
186203 strlcpy(info->bus_info, pci_name(adapter->pdev),
187204 sizeof(info->bus_info));
188205 info->regdump_len = get_regs_len(dev);
189206
190
- if (!adapter->params.fw_vers)
191
- strcpy(info->fw_version, "N/A");
192
- else
207
+ if (adapter->params.fw_vers)
193208 snprintf(info->fw_version, sizeof(info->fw_version),
194209 "%u.%u.%u.%u, TP %u.%u.%u.%u",
195210 FW_HDR_FW_VER_MAJOR_G(adapter->params.fw_vers),
....@@ -224,6 +239,9 @@
224239 } else if (stringset == ETH_SS_PRIV_FLAGS) {
225240 memcpy(data, cxgb4_priv_flags_strings,
226241 sizeof(cxgb4_priv_flags_strings));
242
+ } else if (stringset == ETH_SS_TEST) {
243
+ memcpy(data, cxgb4_selftest_strings,
244
+ sizeof(cxgb4_selftest_strings));
227245 }
228246 }
229247
....@@ -232,12 +250,22 @@
232250 */
233251 struct queue_port_stats {
234252 u64 tso;
253
+ u64 uso;
235254 u64 tx_csum;
236255 u64 rx_csum;
237256 u64 vlan_ex;
238257 u64 vlan_ins;
239258 u64 gro_pkts;
240259 u64 gro_merged;
260
+#if IS_ENABLED(CONFIG_CHELSIO_TLS_DEVICE)
261
+ u64 tx_tls_encrypted_packets;
262
+ u64 tx_tls_encrypted_bytes;
263
+ u64 tx_tls_ctx;
264
+ u64 tx_tls_ooo;
265
+ u64 tx_tls_skip_no_sync_data;
266
+ u64 tx_tls_drop_no_sync_data;
267
+ u64 tx_tls_drop_bypass_req;
268
+#endif
241269 };
242270
243271 struct adapter_stats {
....@@ -252,13 +280,18 @@
252280 const struct port_info *p,
253281 struct queue_port_stats *s)
254282 {
255
- int i;
256283 const struct sge_eth_txq *tx = &adap->sge.ethtxq[p->first_qset];
257284 const struct sge_eth_rxq *rx = &adap->sge.ethrxq[p->first_qset];
285
+#if IS_ENABLED(CONFIG_CHELSIO_TLS_DEVICE)
286
+ const struct ch_ktls_port_stats_debug *ktls_stats;
287
+#endif
288
+ struct sge_eohw_txq *eohw_tx;
289
+ unsigned int i;
258290
259291 memset(s, 0, sizeof(*s));
260292 for (i = 0; i < p->nqsets; i++, rx++, tx++) {
261293 s->tso += tx->tso;
294
+ s->uso += tx->uso;
262295 s->tx_csum += tx->tx_cso;
263296 s->rx_csum += rx->stats.rx_cso;
264297 s->vlan_ex += rx->stats.vlan_ex;
....@@ -266,6 +299,31 @@
266299 s->gro_pkts += rx->stats.lro_pkts;
267300 s->gro_merged += rx->stats.lro_merged;
268301 }
302
+
303
+ if (adap->sge.eohw_txq) {
304
+ eohw_tx = &adap->sge.eohw_txq[p->first_qset];
305
+ for (i = 0; i < p->nqsets; i++, eohw_tx++) {
306
+ s->tso += eohw_tx->tso;
307
+ s->uso += eohw_tx->uso;
308
+ s->tx_csum += eohw_tx->tx_cso;
309
+ s->vlan_ins += eohw_tx->vlan_ins;
310
+ }
311
+ }
312
+#if IS_ENABLED(CONFIG_CHELSIO_TLS_DEVICE)
313
+ ktls_stats = &adap->ch_ktls_stats.ktls_port[p->port_id];
314
+ s->tx_tls_encrypted_packets =
315
+ atomic64_read(&ktls_stats->ktls_tx_encrypted_packets);
316
+ s->tx_tls_encrypted_bytes =
317
+ atomic64_read(&ktls_stats->ktls_tx_encrypted_bytes);
318
+ s->tx_tls_ctx = atomic64_read(&ktls_stats->ktls_tx_ctx);
319
+ s->tx_tls_ooo = atomic64_read(&ktls_stats->ktls_tx_ooo);
320
+ s->tx_tls_skip_no_sync_data =
321
+ atomic64_read(&ktls_stats->ktls_tx_skip_no_sync_data);
322
+ s->tx_tls_drop_no_sync_data =
323
+ atomic64_read(&ktls_stats->ktls_tx_drop_no_sync_data);
324
+ s->tx_tls_drop_bypass_req =
325
+ atomic64_read(&ktls_stats->ktls_tx_drop_bypass_req);
326
+#endif
269327 }
270328
271329 static void collect_adapter_stats(struct adapter *adap, struct adapter_stats *s)
....@@ -442,12 +500,14 @@
442500 * Link Mode Mask.
443501 */
444502 static void fw_caps_to_lmm(enum fw_port_type port_type,
445
- unsigned int fw_caps,
503
+ fw_port_cap32_t fw_caps,
446504 unsigned long *link_mode_mask)
447505 {
448506 #define SET_LMM(__lmm_name) \
449
- __set_bit(ETHTOOL_LINK_MODE_ ## __lmm_name ## _BIT, \
450
- link_mode_mask)
507
+ do { \
508
+ __set_bit(ETHTOOL_LINK_MODE_ ## __lmm_name ## _BIT, \
509
+ link_mode_mask); \
510
+ } while (0)
451511
452512 #define FW_CAPS_TO_LMM(__fw_name, __lmm_name) \
453513 do { \
....@@ -541,7 +601,7 @@
541601 case FW_PORT_TYPE_CR4_QSFP:
542602 SET_LMM(FIBRE);
543603 FW_CAPS_TO_LMM(SPEED_1G, 1000baseT_Full);
544
- FW_CAPS_TO_LMM(SPEED_10G, 10000baseSR_Full);
604
+ FW_CAPS_TO_LMM(SPEED_10G, 10000baseKR_Full);
545605 FW_CAPS_TO_LMM(SPEED_40G, 40000baseSR4_Full);
546606 FW_CAPS_TO_LMM(SPEED_25G, 25000baseCR_Full);
547607 FW_CAPS_TO_LMM(SPEED_50G, 50000baseCR2_Full);
....@@ -550,6 +610,13 @@
550610
551611 default:
552612 break;
613
+ }
614
+
615
+ if (fw_caps & FW_PORT_CAP32_FEC_V(FW_PORT_CAP32_FEC_M)) {
616
+ FW_CAPS_TO_LMM(FEC_RS, FEC_RS);
617
+ FW_CAPS_TO_LMM(FEC_BASER_RS, FEC_BASER);
618
+ } else {
619
+ SET_LMM(FEC_NONE);
553620 }
554621
555622 FW_CAPS_TO_LMM(ANEG, Autoneg);
....@@ -563,7 +630,7 @@
563630 /**
564631 * lmm_to_fw_caps - translate ethtool Link Mode Mask to Firmware
565632 * capabilities
566
- * @et_lmm: ethtool Link Mode Mask
633
+ * @link_mode_mask: ethtool Link Mode Mask
567634 *
568635 * Translate ethtool Link Mode Mask into a Firmware Port capabilities
569636 * value.
....@@ -623,7 +690,10 @@
623690
624691 fw_caps_to_lmm(pi->port_type, pi->link_cfg.pcaps,
625692 link_ksettings->link_modes.supported);
626
- fw_caps_to_lmm(pi->port_type, pi->link_cfg.acaps,
693
+ fw_caps_to_lmm(pi->port_type,
694
+ t4_link_acaps(pi->adapter,
695
+ pi->lport,
696
+ &pi->link_cfg),
627697 link_ksettings->link_modes.advertising);
628698 fw_caps_to_lmm(pi->port_type, pi->link_cfg.lpacaps,
629699 link_ksettings->link_modes.lp_advertising);
....@@ -632,22 +702,6 @@
632702 ? pi->link_cfg.speed
633703 : SPEED_UNKNOWN);
634704 base->duplex = DUPLEX_FULL;
635
-
636
- if (pi->link_cfg.fc & PAUSE_RX) {
637
- if (pi->link_cfg.fc & PAUSE_TX) {
638
- ethtool_link_ksettings_add_link_mode(link_ksettings,
639
- advertising,
640
- Pause);
641
- } else {
642
- ethtool_link_ksettings_add_link_mode(link_ksettings,
643
- advertising,
644
- Asym_Pause);
645
- }
646
- } else if (pi->link_cfg.fc & PAUSE_TX) {
647
- ethtool_link_ksettings_add_link_mode(link_ksettings,
648
- advertising,
649
- Asym_Pause);
650
- }
651705
652706 base->autoneg = pi->link_cfg.autoneg;
653707 if (pi->link_cfg.pcaps & FW_PORT_CAP32_ANEG)
....@@ -679,18 +733,15 @@
679733 base->autoneg == AUTONEG_DISABLE) {
680734 fw_caps = speed_to_fw_caps(base->speed);
681735
682
- /* Must only specify a single speed which must be supported
683
- * as part of the Physical Port Capabilities.
684
- */
685
- if ((fw_caps & (fw_caps - 1)) != 0 ||
686
- !(lc->pcaps & fw_caps))
736
+ /* Speed must be supported by Physical Port Capabilities. */
737
+ if (!(lc->pcaps & fw_caps))
687738 return -EINVAL;
688739
689740 lc->speed_caps = fw_caps;
690741 lc->acaps = fw_caps;
691742 } else {
692743 fw_caps =
693
- lmm_to_fw_caps(link_ksettings->link_modes.advertising);
744
+ lmm_to_fw_caps(link_ksettings->link_modes.advertising);
694745 if (!(lc->pcaps & fw_caps))
695746 return -EINVAL;
696747 lc->speed_caps = 0;
....@@ -812,8 +863,8 @@
812863 struct port_info *p = netdev_priv(dev);
813864
814865 epause->autoneg = (p->link_cfg.requested_fc & PAUSE_AUTONEG) != 0;
815
- epause->rx_pause = (p->link_cfg.fc & PAUSE_RX) != 0;
816
- epause->tx_pause = (p->link_cfg.fc & PAUSE_TX) != 0;
866
+ epause->rx_pause = (p->link_cfg.advertised_fc & PAUSE_RX) != 0;
867
+ epause->tx_pause = (p->link_cfg.advertised_fc & PAUSE_TX) != 0;
817868 }
818869
819870 static int set_pauseparam(struct net_device *dev,
....@@ -869,7 +920,7 @@
869920 e->rx_pending < MIN_FL_ENTRIES || e->tx_pending < MIN_TXQ_ENTRIES)
870921 return -EINVAL;
871922
872
- if (adapter->flags & FULL_INIT_DONE)
923
+ if (adapter->flags & CXGB4_FULL_INIT_DONE)
873924 return -EBUSY;
874925
875926 for (i = 0; i < pi->nqsets; ++i) {
....@@ -926,11 +977,190 @@
926977 return q->rspq.adaptive_rx;
927978 }
928979
929
-static int set_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
980
+/* Return the current global Adapter SGE Doorbell Queue Timer Tick for all
981
+ * Ethernet TX Queues.
982
+ */
983
+static int get_dbqtimer_tick(struct net_device *dev)
930984 {
931
- set_adaptive_rx_setting(dev, c->use_adaptive_rx_coalesce);
932
- return set_rx_intr_params(dev, c->rx_coalesce_usecs,
933
- c->rx_max_coalesced_frames);
985
+ struct port_info *pi = netdev_priv(dev);
986
+ struct adapter *adap = pi->adapter;
987
+
988
+ if (!(adap->flags & CXGB4_SGE_DBQ_TIMER))
989
+ return 0;
990
+
991
+ return adap->sge.dbqtimer_tick;
992
+}
993
+
994
+/* Return the SGE Doorbell Queue Timer Value for the Ethernet TX Queues
995
+ * associated with a Network Device.
996
+ */
997
+static int get_dbqtimer(struct net_device *dev)
998
+{
999
+ struct port_info *pi = netdev_priv(dev);
1000
+ struct adapter *adap = pi->adapter;
1001
+ struct sge_eth_txq *txq;
1002
+
1003
+ txq = &adap->sge.ethtxq[pi->first_qset];
1004
+
1005
+ if (!(adap->flags & CXGB4_SGE_DBQ_TIMER))
1006
+ return 0;
1007
+
1008
+ /* all of the TX Queues use the same Timer Index */
1009
+ return adap->sge.dbqtimer_val[txq->dbqtimerix];
1010
+}
1011
+
1012
+/* Set the global Adapter SGE Doorbell Queue Timer Tick for all Ethernet TX
1013
+ * Queues. This is the fundamental "Tick" that sets the scale of values which
1014
+ * can be used. Individual Ethernet TX Queues index into a relatively small
1015
+ * array of Tick Multipliers. Changing the base Tick will thus change all of
1016
+ * the resulting Timer Values associated with those multipliers for all
1017
+ * Ethernet TX Queues.
1018
+ */
1019
+static int set_dbqtimer_tick(struct net_device *dev, int usecs)
1020
+{
1021
+ struct port_info *pi = netdev_priv(dev);
1022
+ struct adapter *adap = pi->adapter;
1023
+ struct sge *s = &adap->sge;
1024
+ u32 param, val;
1025
+ int ret;
1026
+
1027
+ if (!(adap->flags & CXGB4_SGE_DBQ_TIMER))
1028
+ return 0;
1029
+
1030
+ /* return early if it's the same Timer Tick we're already using */
1031
+ if (s->dbqtimer_tick == usecs)
1032
+ return 0;
1033
+
1034
+ /* attempt to set the new Timer Tick value */
1035
+ param = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) |
1036
+ FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_DBQ_TIMERTICK));
1037
+ val = usecs;
1038
+ ret = t4_set_params(adap, adap->mbox, adap->pf, 0, 1, &param, &val);
1039
+ if (ret)
1040
+ return ret;
1041
+ s->dbqtimer_tick = usecs;
1042
+
1043
+ /* if successful, reread resulting dependent Timer values */
1044
+ ret = t4_read_sge_dbqtimers(adap, ARRAY_SIZE(s->dbqtimer_val),
1045
+ s->dbqtimer_val);
1046
+ return ret;
1047
+}
1048
+
1049
+/* Set the SGE Doorbell Queue Timer Value for the Ethernet TX Queues
1050
+ * associated with a Network Device. There is a relatively small array of
1051
+ * possible Timer Values so we need to pick the closest value available.
1052
+ */
1053
+static int set_dbqtimer(struct net_device *dev, int usecs)
1054
+{
1055
+ int qix, timerix, min_timerix, delta, min_delta;
1056
+ struct port_info *pi = netdev_priv(dev);
1057
+ struct adapter *adap = pi->adapter;
1058
+ struct sge *s = &adap->sge;
1059
+ struct sge_eth_txq *txq;
1060
+ u32 param, val;
1061
+ int ret;
1062
+
1063
+ if (!(adap->flags & CXGB4_SGE_DBQ_TIMER))
1064
+ return 0;
1065
+
1066
+ /* Find the SGE Doorbell Timer Value that's closest to the requested
1067
+ * value.
1068
+ */
1069
+ min_delta = INT_MAX;
1070
+ min_timerix = 0;
1071
+ for (timerix = 0; timerix < ARRAY_SIZE(s->dbqtimer_val); timerix++) {
1072
+ delta = s->dbqtimer_val[timerix] - usecs;
1073
+ if (delta < 0)
1074
+ delta = -delta;
1075
+ if (delta < min_delta) {
1076
+ min_delta = delta;
1077
+ min_timerix = timerix;
1078
+ }
1079
+ }
1080
+
1081
+ /* Return early if it's the same Timer Index we're already using.
1082
+ * We use the same Timer Index for all of the TX Queues for an
1083
+ * interface so it's only necessary to check the first one.
1084
+ */
1085
+ txq = &s->ethtxq[pi->first_qset];
1086
+ if (txq->dbqtimerix == min_timerix)
1087
+ return 0;
1088
+
1089
+ for (qix = 0; qix < pi->nqsets; qix++, txq++) {
1090
+ if (adap->flags & CXGB4_FULL_INIT_DONE) {
1091
+ param =
1092
+ (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DMAQ) |
1093
+ FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DMAQ_EQ_TIMERIX) |
1094
+ FW_PARAMS_PARAM_YZ_V(txq->q.cntxt_id));
1095
+ val = min_timerix;
1096
+ ret = t4_set_params(adap, adap->mbox, adap->pf, 0,
1097
+ 1, &param, &val);
1098
+ if (ret)
1099
+ return ret;
1100
+ }
1101
+ txq->dbqtimerix = min_timerix;
1102
+ }
1103
+ return 0;
1104
+}
1105
+
1106
+/* Set the global Adapter SGE Doorbell Queue Timer Tick for all Ethernet TX
1107
+ * Queues and the Timer Value for the Ethernet TX Queues associated with a
1108
+ * Network Device. Since changing the global Tick changes all of the
1109
+ * available Timer Values, we need to do this first before selecting the
1110
+ * resulting closest Timer Value. Moreover, since the Tick is global,
1111
+ * changing it affects the Timer Values for all Network Devices on the
1112
+ * adapter. So, before changing the Tick, we grab all of the current Timer
1113
+ * Values for other Network Devices on this Adapter and then attempt to select
1114
+ * new Timer Values which are close to the old values ...
1115
+ */
1116
+static int set_dbqtimer_tickval(struct net_device *dev,
1117
+ int tick_usecs, int timer_usecs)
1118
+{
1119
+ struct port_info *pi = netdev_priv(dev);
1120
+ struct adapter *adap = pi->adapter;
1121
+ int timer[MAX_NPORTS];
1122
+ unsigned int port;
1123
+ int ret;
1124
+
1125
+ /* Grab the other adapter Network Interface current timers and fill in
1126
+ * the new one for this Network Interface.
1127
+ */
1128
+ for_each_port(adap, port)
1129
+ if (port == pi->port_id)
1130
+ timer[port] = timer_usecs;
1131
+ else
1132
+ timer[port] = get_dbqtimer(adap->port[port]);
1133
+
1134
+ /* Change the global Tick first ... */
1135
+ ret = set_dbqtimer_tick(dev, tick_usecs);
1136
+ if (ret)
1137
+ return ret;
1138
+
1139
+ /* ... and then set all of the Network Interface Timer Values ... */
1140
+ for_each_port(adap, port) {
1141
+ ret = set_dbqtimer(adap->port[port], timer[port]);
1142
+ if (ret)
1143
+ return ret;
1144
+ }
1145
+
1146
+ return 0;
1147
+}
1148
+
1149
+static int set_coalesce(struct net_device *dev,
1150
+ struct ethtool_coalesce *coalesce)
1151
+{
1152
+ int ret;
1153
+
1154
+ set_adaptive_rx_setting(dev, coalesce->use_adaptive_rx_coalesce);
1155
+
1156
+ ret = set_rx_intr_params(dev, coalesce->rx_coalesce_usecs,
1157
+ coalesce->rx_max_coalesced_frames);
1158
+ if (ret)
1159
+ return ret;
1160
+
1161
+ return set_dbqtimer_tickval(dev,
1162
+ coalesce->tx_coalesce_usecs_irq,
1163
+ coalesce->tx_coalesce_usecs);
9341164 }
9351165
9361166 static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
....@@ -943,6 +1173,8 @@
9431173 c->rx_max_coalesced_frames = (rq->intr_params & QINTR_CNT_EN_F) ?
9441174 adap->sge.counter_val[rq->pktcnt_idx] : 0;
9451175 c->use_adaptive_rx_coalesce = get_adaptive_rx_setting(dev);
1176
+ c->tx_coalesce_usecs_irq = get_dbqtimer_tick(dev);
1177
+ c->tx_coalesce_usecs = get_dbqtimer(dev);
9461178 return 0;
9471179 }
9481180
....@@ -1045,15 +1277,225 @@
10451277 return err;
10461278 }
10471279
1048
-static int set_flash(struct net_device *netdev, struct ethtool_flash *ef)
1280
+static int cxgb4_ethtool_flash_bootcfg(struct net_device *netdev,
1281
+ const u8 *data, u32 size)
10491282 {
1283
+ struct adapter *adap = netdev2adap(netdev);
10501284 int ret;
1051
- const struct firmware *fw;
1285
+
1286
+ ret = t4_load_bootcfg(adap, data, size);
1287
+ if (ret)
1288
+ dev_err(adap->pdev_dev, "Failed to load boot cfg image\n");
1289
+
1290
+ return ret;
1291
+}
1292
+
1293
+static int cxgb4_ethtool_flash_boot(struct net_device *netdev,
1294
+ const u8 *bdata, u32 size)
1295
+{
1296
+ struct adapter *adap = netdev2adap(netdev);
1297
+ unsigned int offset;
1298
+ u8 *data;
1299
+ int ret;
1300
+
1301
+ data = kmemdup(bdata, size, GFP_KERNEL);
1302
+ if (!data)
1303
+ return -ENOMEM;
1304
+
1305
+ offset = OFFSET_G(t4_read_reg(adap, PF_REG(0, PCIE_PF_EXPROM_OFST_A)));
1306
+
1307
+ ret = t4_load_boot(adap, data, offset, size);
1308
+ if (ret)
1309
+ dev_err(adap->pdev_dev, "Failed to load boot image\n");
1310
+
1311
+ kfree(data);
1312
+ return ret;
1313
+}
1314
+
1315
+#define CXGB4_PHY_SIG 0x130000ea
1316
+
1317
+static int cxgb4_validate_phy_image(const u8 *data, u32 *size)
1318
+{
1319
+ struct cxgb4_fw_data *header;
1320
+
1321
+ header = (struct cxgb4_fw_data *)data;
1322
+ if (be32_to_cpu(header->signature) != CXGB4_PHY_SIG)
1323
+ return -EINVAL;
1324
+
1325
+ return 0;
1326
+}
1327
+
1328
+static int cxgb4_ethtool_flash_phy(struct net_device *netdev,
1329
+ const u8 *data, u32 size)
1330
+{
1331
+ struct adapter *adap = netdev2adap(netdev);
1332
+ int ret;
1333
+
1334
+ ret = cxgb4_validate_phy_image(data, NULL);
1335
+ if (ret) {
1336
+ dev_err(adap->pdev_dev, "PHY signature mismatch\n");
1337
+ return ret;
1338
+ }
1339
+
1340
+ /* We have to RESET the chip/firmware because we need the
1341
+ * chip in uninitialized state for loading new PHY image.
1342
+ * Otherwise, the running firmware will only store the PHY
1343
+ * image in local RAM which will be lost after next reset.
1344
+ */
1345
+ ret = t4_fw_reset(adap, adap->mbox, PIORSTMODE_F | PIORST_F);
1346
+ if (ret < 0) {
1347
+ dev_err(adap->pdev_dev,
1348
+ "Set FW to RESET for flashing PHY FW failed. ret: %d\n",
1349
+ ret);
1350
+ return ret;
1351
+ }
1352
+
1353
+ ret = t4_load_phy_fw(adap, MEMWIN_NIC, NULL, data, size);
1354
+ if (ret < 0) {
1355
+ dev_err(adap->pdev_dev, "Failed to load PHY FW. ret: %d\n",
1356
+ ret);
1357
+ return ret;
1358
+ }
1359
+
1360
+ return 0;
1361
+}
1362
+
1363
+static int cxgb4_ethtool_flash_fw(struct net_device *netdev,
1364
+ const u8 *data, u32 size)
1365
+{
10521366 struct adapter *adap = netdev2adap(netdev);
10531367 unsigned int mbox = PCIE_FW_MASTER_M + 1;
1054
- u32 pcie_fw;
1368
+ int ret;
1369
+
1370
+ /* If the adapter has been fully initialized then we'll go ahead and
1371
+ * try to get the firmware's cooperation in upgrading to the new
1372
+ * firmware image otherwise we'll try to do the entire job from the
1373
+ * host ... and we always "force" the operation in this path.
1374
+ */
1375
+ if (adap->flags & CXGB4_FULL_INIT_DONE)
1376
+ mbox = adap->mbox;
1377
+
1378
+ ret = t4_fw_upgrade(adap, mbox, data, size, 1);
1379
+ if (ret)
1380
+ dev_err(adap->pdev_dev,
1381
+ "Failed to flash firmware\n");
1382
+
1383
+ return ret;
1384
+}
1385
+
1386
+static int cxgb4_ethtool_flash_region(struct net_device *netdev,
1387
+ const u8 *data, u32 size, u32 region)
1388
+{
1389
+ struct adapter *adap = netdev2adap(netdev);
1390
+ int ret;
1391
+
1392
+ switch (region) {
1393
+ case CXGB4_ETHTOOL_FLASH_FW:
1394
+ ret = cxgb4_ethtool_flash_fw(netdev, data, size);
1395
+ break;
1396
+ case CXGB4_ETHTOOL_FLASH_PHY:
1397
+ ret = cxgb4_ethtool_flash_phy(netdev, data, size);
1398
+ break;
1399
+ case CXGB4_ETHTOOL_FLASH_BOOT:
1400
+ ret = cxgb4_ethtool_flash_boot(netdev, data, size);
1401
+ break;
1402
+ case CXGB4_ETHTOOL_FLASH_BOOTCFG:
1403
+ ret = cxgb4_ethtool_flash_bootcfg(netdev, data, size);
1404
+ break;
1405
+ default:
1406
+ ret = -EOPNOTSUPP;
1407
+ break;
1408
+ }
1409
+
1410
+ if (!ret)
1411
+ dev_info(adap->pdev_dev,
1412
+ "loading %s successful, reload cxgb4 driver\n",
1413
+ flash_region_strings[region]);
1414
+ return ret;
1415
+}
1416
+
1417
+#define CXGB4_FW_SIG 0x4368656c
1418
+#define CXGB4_FW_SIG_OFFSET 0x160
1419
+
1420
+static int cxgb4_validate_fw_image(const u8 *data, u32 *size)
1421
+{
1422
+ struct cxgb4_fw_data *header;
1423
+
1424
+ header = (struct cxgb4_fw_data *)&data[CXGB4_FW_SIG_OFFSET];
1425
+ if (be32_to_cpu(header->signature) != CXGB4_FW_SIG)
1426
+ return -EINVAL;
1427
+
1428
+ if (size)
1429
+ *size = be16_to_cpu(((struct fw_hdr *)data)->len512) * 512;
1430
+
1431
+ return 0;
1432
+}
1433
+
1434
+static int cxgb4_validate_bootcfg_image(const u8 *data, u32 *size)
1435
+{
1436
+ struct cxgb4_bootcfg_data *header;
1437
+
1438
+ header = (struct cxgb4_bootcfg_data *)data;
1439
+ if (le16_to_cpu(header->signature) != BOOT_CFG_SIG)
1440
+ return -EINVAL;
1441
+
1442
+ return 0;
1443
+}
1444
+
1445
+static int cxgb4_validate_boot_image(const u8 *data, u32 *size)
1446
+{
1447
+ struct cxgb4_pci_exp_rom_header *exp_header;
1448
+ struct cxgb4_pcir_data *pcir_header;
1449
+ struct legacy_pci_rom_hdr *header;
1450
+ const u8 *cur_header = data;
1451
+ u16 pcir_offset;
1452
+
1453
+ exp_header = (struct cxgb4_pci_exp_rom_header *)data;
1454
+
1455
+ if (le16_to_cpu(exp_header->signature) != BOOT_SIGNATURE)
1456
+ return -EINVAL;
1457
+
1458
+ if (size) {
1459
+ do {
1460
+ header = (struct legacy_pci_rom_hdr *)cur_header;
1461
+ pcir_offset = le16_to_cpu(header->pcir_offset);
1462
+ pcir_header = (struct cxgb4_pcir_data *)(cur_header +
1463
+ pcir_offset);
1464
+
1465
+ *size += header->size512 * 512;
1466
+ cur_header += header->size512 * 512;
1467
+ } while (!(pcir_header->indicator & CXGB4_HDR_INDI));
1468
+ }
1469
+
1470
+ return 0;
1471
+}
1472
+
1473
+static int cxgb4_ethtool_get_flash_region(const u8 *data, u32 *size)
1474
+{
1475
+ if (!cxgb4_validate_fw_image(data, size))
1476
+ return CXGB4_ETHTOOL_FLASH_FW;
1477
+ if (!cxgb4_validate_boot_image(data, size))
1478
+ return CXGB4_ETHTOOL_FLASH_BOOT;
1479
+ if (!cxgb4_validate_phy_image(data, size))
1480
+ return CXGB4_ETHTOOL_FLASH_PHY;
1481
+ if (!cxgb4_validate_bootcfg_image(data, size))
1482
+ return CXGB4_ETHTOOL_FLASH_BOOTCFG;
1483
+
1484
+ return -EOPNOTSUPP;
1485
+}
1486
+
1487
+static int set_flash(struct net_device *netdev, struct ethtool_flash *ef)
1488
+{
1489
+ struct adapter *adap = netdev2adap(netdev);
1490
+ const struct firmware *fw;
10551491 unsigned int master;
10561492 u8 master_vld = 0;
1493
+ const u8 *fw_data;
1494
+ size_t fw_size;
1495
+ u32 size = 0;
1496
+ u32 pcie_fw;
1497
+ int region;
1498
+ int ret;
10571499
10581500 pcie_fw = t4_read_reg(adap, PCIE_FW_A);
10591501 master = PCIE_FW_MASTER_G(pcie_fw);
....@@ -1071,19 +1513,32 @@
10711513 if (ret < 0)
10721514 return ret;
10731515
1074
- /* If the adapter has been fully initialized then we'll go ahead and
1075
- * try to get the firmware's cooperation in upgrading to the new
1076
- * firmware image otherwise we'll try to do the entire job from the
1077
- * host ... and we always "force" the operation in this path.
1078
- */
1079
- if (adap->flags & FULL_INIT_DONE)
1080
- mbox = adap->mbox;
1516
+ fw_data = fw->data;
1517
+ fw_size = fw->size;
1518
+ if (ef->region == ETHTOOL_FLASH_ALL_REGIONS) {
1519
+ while (fw_size > 0) {
1520
+ size = 0;
1521
+ region = cxgb4_ethtool_get_flash_region(fw_data, &size);
1522
+ if (region < 0 || !size) {
1523
+ ret = region;
1524
+ goto out_free_fw;
1525
+ }
10811526
1082
- ret = t4_fw_upgrade(adap, mbox, fw->data, fw->size, 1);
1527
+ ret = cxgb4_ethtool_flash_region(netdev, fw_data, size,
1528
+ region);
1529
+ if (ret)
1530
+ goto out_free_fw;
1531
+
1532
+ fw_data += size;
1533
+ fw_size -= size;
1534
+ }
1535
+ } else {
1536
+ ret = cxgb4_ethtool_flash_region(netdev, fw_data, fw_size,
1537
+ ef->region);
1538
+ }
1539
+
1540
+out_free_fw:
10831541 release_firmware(fw);
1084
- if (!ret)
1085
- dev_info(adap->pdev_dev,
1086
- "loaded firmware %s, reload cxgb4 driver\n", ef->data);
10871542 return ret;
10881543 }
10891544
....@@ -1155,7 +1610,7 @@
11551610 return 0;
11561611
11571612 /* Interface must be brought up atleast once */
1158
- if (pi->adapter->flags & FULL_INIT_DONE) {
1613
+ if (pi->adapter->flags & CXGB4_FULL_INIT_DONE) {
11591614 for (i = 0; i < pi->rss_size; i++)
11601615 pi->rss[i] = p[i];
11611616
....@@ -1165,10 +1620,118 @@
11651620 return -EPERM;
11661621 }
11671622
1623
+static struct filter_entry *cxgb4_get_filter_entry(struct adapter *adap,
1624
+ u32 ftid)
1625
+{
1626
+ struct tid_info *t = &adap->tids;
1627
+
1628
+ if (ftid >= t->hpftid_base && ftid < t->hpftid_base + t->nhpftids)
1629
+ return &t->hpftid_tab[ftid - t->hpftid_base];
1630
+
1631
+ if (ftid >= t->ftid_base && ftid < t->ftid_base + t->nftids)
1632
+ return &t->ftid_tab[ftid - t->ftid_base];
1633
+
1634
+ return lookup_tid(t, ftid);
1635
+}
1636
+
1637
+static void cxgb4_fill_filter_rule(struct ethtool_rx_flow_spec *fs,
1638
+ struct ch_filter_specification *dfs)
1639
+{
1640
+ switch (dfs->val.proto) {
1641
+ case IPPROTO_TCP:
1642
+ if (dfs->type)
1643
+ fs->flow_type = TCP_V6_FLOW;
1644
+ else
1645
+ fs->flow_type = TCP_V4_FLOW;
1646
+ break;
1647
+ case IPPROTO_UDP:
1648
+ if (dfs->type)
1649
+ fs->flow_type = UDP_V6_FLOW;
1650
+ else
1651
+ fs->flow_type = UDP_V4_FLOW;
1652
+ break;
1653
+ }
1654
+
1655
+ if (dfs->type) {
1656
+ fs->h_u.tcp_ip6_spec.psrc = cpu_to_be16(dfs->val.fport);
1657
+ fs->m_u.tcp_ip6_spec.psrc = cpu_to_be16(dfs->mask.fport);
1658
+ fs->h_u.tcp_ip6_spec.pdst = cpu_to_be16(dfs->val.lport);
1659
+ fs->m_u.tcp_ip6_spec.pdst = cpu_to_be16(dfs->mask.lport);
1660
+ memcpy(&fs->h_u.tcp_ip6_spec.ip6src, &dfs->val.fip[0],
1661
+ sizeof(fs->h_u.tcp_ip6_spec.ip6src));
1662
+ memcpy(&fs->m_u.tcp_ip6_spec.ip6src, &dfs->mask.fip[0],
1663
+ sizeof(fs->m_u.tcp_ip6_spec.ip6src));
1664
+ memcpy(&fs->h_u.tcp_ip6_spec.ip6dst, &dfs->val.lip[0],
1665
+ sizeof(fs->h_u.tcp_ip6_spec.ip6dst));
1666
+ memcpy(&fs->m_u.tcp_ip6_spec.ip6dst, &dfs->mask.lip[0],
1667
+ sizeof(fs->m_u.tcp_ip6_spec.ip6dst));
1668
+ fs->h_u.tcp_ip6_spec.tclass = dfs->val.tos;
1669
+ fs->m_u.tcp_ip6_spec.tclass = dfs->mask.tos;
1670
+ } else {
1671
+ fs->h_u.tcp_ip4_spec.psrc = cpu_to_be16(dfs->val.fport);
1672
+ fs->m_u.tcp_ip4_spec.psrc = cpu_to_be16(dfs->mask.fport);
1673
+ fs->h_u.tcp_ip4_spec.pdst = cpu_to_be16(dfs->val.lport);
1674
+ fs->m_u.tcp_ip4_spec.pdst = cpu_to_be16(dfs->mask.lport);
1675
+ memcpy(&fs->h_u.tcp_ip4_spec.ip4src, &dfs->val.fip[0],
1676
+ sizeof(fs->h_u.tcp_ip4_spec.ip4src));
1677
+ memcpy(&fs->m_u.tcp_ip4_spec.ip4src, &dfs->mask.fip[0],
1678
+ sizeof(fs->m_u.tcp_ip4_spec.ip4src));
1679
+ memcpy(&fs->h_u.tcp_ip4_spec.ip4dst, &dfs->val.lip[0],
1680
+ sizeof(fs->h_u.tcp_ip4_spec.ip4dst));
1681
+ memcpy(&fs->m_u.tcp_ip4_spec.ip4dst, &dfs->mask.lip[0],
1682
+ sizeof(fs->m_u.tcp_ip4_spec.ip4dst));
1683
+ fs->h_u.tcp_ip4_spec.tos = dfs->val.tos;
1684
+ fs->m_u.tcp_ip4_spec.tos = dfs->mask.tos;
1685
+ }
1686
+ fs->h_ext.vlan_tci = cpu_to_be16(dfs->val.ivlan);
1687
+ fs->m_ext.vlan_tci = cpu_to_be16(dfs->mask.ivlan);
1688
+ fs->flow_type |= FLOW_EXT;
1689
+
1690
+ if (dfs->action == FILTER_DROP)
1691
+ fs->ring_cookie = RX_CLS_FLOW_DISC;
1692
+ else
1693
+ fs->ring_cookie = dfs->iq;
1694
+}
1695
+
1696
+static int cxgb4_ntuple_get_filter(struct net_device *dev,
1697
+ struct ethtool_rxnfc *cmd,
1698
+ unsigned int loc)
1699
+{
1700
+ const struct port_info *pi = netdev_priv(dev);
1701
+ struct adapter *adap = netdev2adap(dev);
1702
+ struct filter_entry *f;
1703
+ int ftid;
1704
+
1705
+ if (!(adap->flags & CXGB4_FULL_INIT_DONE))
1706
+ return -EAGAIN;
1707
+
1708
+ /* Check for maximum filter range */
1709
+ if (!adap->ethtool_filters)
1710
+ return -EOPNOTSUPP;
1711
+
1712
+ if (loc >= adap->ethtool_filters->nentries)
1713
+ return -ERANGE;
1714
+
1715
+ if (!test_bit(loc, adap->ethtool_filters->port[pi->port_id].bmap))
1716
+ return -ENOENT;
1717
+
1718
+ ftid = adap->ethtool_filters->port[pi->port_id].loc_array[loc];
1719
+
1720
+ /* Fetch filter_entry */
1721
+ f = cxgb4_get_filter_entry(adap, ftid);
1722
+
1723
+ cxgb4_fill_filter_rule(&cmd->fs, &f->fs);
1724
+
1725
+ return 0;
1726
+}
1727
+
11681728 static int get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info,
11691729 u32 *rules)
11701730 {
11711731 const struct port_info *pi = netdev_priv(dev);
1732
+ struct adapter *adap = netdev2adap(dev);
1733
+ unsigned int count = 0, index = 0;
1734
+ int ret = 0;
11721735
11731736 switch (info->cmd) {
11741737 case ETHTOOL_GRXFH: {
....@@ -1224,8 +1787,152 @@
12241787 case ETHTOOL_GRXRINGS:
12251788 info->data = pi->nqsets;
12261789 return 0;
1790
+ case ETHTOOL_GRXCLSRLCNT:
1791
+ info->rule_cnt =
1792
+ adap->ethtool_filters->port[pi->port_id].in_use;
1793
+ return 0;
1794
+ case ETHTOOL_GRXCLSRULE:
1795
+ return cxgb4_ntuple_get_filter(dev, info, info->fs.location);
1796
+ case ETHTOOL_GRXCLSRLALL:
1797
+ info->data = adap->ethtool_filters->nentries;
1798
+ while (count < info->rule_cnt) {
1799
+ ret = cxgb4_ntuple_get_filter(dev, info, index);
1800
+ if (!ret)
1801
+ rules[count++] = index;
1802
+ index++;
1803
+ }
1804
+ return 0;
12271805 }
1806
+
12281807 return -EOPNOTSUPP;
1808
+}
1809
+
1810
+static int cxgb4_ntuple_del_filter(struct net_device *dev,
1811
+ struct ethtool_rxnfc *cmd)
1812
+{
1813
+ struct cxgb4_ethtool_filter_info *filter_info;
1814
+ struct adapter *adapter = netdev2adap(dev);
1815
+ struct port_info *pi = netdev_priv(dev);
1816
+ struct filter_entry *f;
1817
+ u32 filter_id;
1818
+ int ret;
1819
+
1820
+ if (!(adapter->flags & CXGB4_FULL_INIT_DONE))
1821
+ return -EAGAIN; /* can still change nfilters */
1822
+
1823
+ if (!adapter->ethtool_filters)
1824
+ return -EOPNOTSUPP;
1825
+
1826
+ if (cmd->fs.location >= adapter->ethtool_filters->nentries) {
1827
+ dev_err(adapter->pdev_dev,
1828
+ "Location must be < %u",
1829
+ adapter->ethtool_filters->nentries);
1830
+ return -ERANGE;
1831
+ }
1832
+
1833
+ filter_info = &adapter->ethtool_filters->port[pi->port_id];
1834
+
1835
+ if (!test_bit(cmd->fs.location, filter_info->bmap))
1836
+ return -ENOENT;
1837
+
1838
+ filter_id = filter_info->loc_array[cmd->fs.location];
1839
+ f = cxgb4_get_filter_entry(adapter, filter_id);
1840
+
1841
+ if (f->fs.prio)
1842
+ filter_id -= adapter->tids.hpftid_base;
1843
+ else if (!f->fs.hash)
1844
+ filter_id -= (adapter->tids.ftid_base - adapter->tids.nhpftids);
1845
+
1846
+ ret = cxgb4_flow_rule_destroy(dev, f->fs.tc_prio, &f->fs, filter_id);
1847
+ if (ret)
1848
+ goto err;
1849
+
1850
+ clear_bit(cmd->fs.location, filter_info->bmap);
1851
+ filter_info->in_use--;
1852
+
1853
+err:
1854
+ return ret;
1855
+}
1856
+
1857
+/* Add Ethtool n-tuple filters. */
1858
+static int cxgb4_ntuple_set_filter(struct net_device *netdev,
1859
+ struct ethtool_rxnfc *cmd)
1860
+{
1861
+ struct ethtool_rx_flow_spec_input input = {};
1862
+ struct cxgb4_ethtool_filter_info *filter_info;
1863
+ struct adapter *adapter = netdev2adap(netdev);
1864
+ struct port_info *pi = netdev_priv(netdev);
1865
+ struct ch_filter_specification fs;
1866
+ struct ethtool_rx_flow_rule *flow;
1867
+ u32 tid;
1868
+ int ret;
1869
+
1870
+ if (!(adapter->flags & CXGB4_FULL_INIT_DONE))
1871
+ return -EAGAIN; /* can still change nfilters */
1872
+
1873
+ if (!adapter->ethtool_filters)
1874
+ return -EOPNOTSUPP;
1875
+
1876
+ if (cmd->fs.location >= adapter->ethtool_filters->nentries) {
1877
+ dev_err(adapter->pdev_dev,
1878
+ "Location must be < %u",
1879
+ adapter->ethtool_filters->nentries);
1880
+ return -ERANGE;
1881
+ }
1882
+
1883
+ if (test_bit(cmd->fs.location,
1884
+ adapter->ethtool_filters->port[pi->port_id].bmap))
1885
+ return -EEXIST;
1886
+
1887
+ memset(&fs, 0, sizeof(fs));
1888
+
1889
+ input.fs = &cmd->fs;
1890
+ flow = ethtool_rx_flow_rule_create(&input);
1891
+ if (IS_ERR(flow)) {
1892
+ ret = PTR_ERR(flow);
1893
+ goto exit;
1894
+ }
1895
+
1896
+ fs.hitcnts = 1;
1897
+
1898
+ ret = cxgb4_flow_rule_replace(netdev, flow->rule, cmd->fs.location,
1899
+ NULL, &fs, &tid);
1900
+ if (ret)
1901
+ goto free;
1902
+
1903
+ filter_info = &adapter->ethtool_filters->port[pi->port_id];
1904
+
1905
+ if (fs.prio)
1906
+ tid += adapter->tids.hpftid_base;
1907
+ else if (!fs.hash)
1908
+ tid += (adapter->tids.ftid_base - adapter->tids.nhpftids);
1909
+
1910
+ filter_info->loc_array[cmd->fs.location] = tid;
1911
+ set_bit(cmd->fs.location, filter_info->bmap);
1912
+ filter_info->in_use++;
1913
+
1914
+free:
1915
+ ethtool_rx_flow_rule_destroy(flow);
1916
+exit:
1917
+ return ret;
1918
+}
1919
+
1920
+static int set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
1921
+{
1922
+ int ret = -EOPNOTSUPP;
1923
+
1924
+ switch (cmd->cmd) {
1925
+ case ETHTOOL_SRXCLSRLINS:
1926
+ ret = cxgb4_ntuple_set_filter(dev, cmd);
1927
+ break;
1928
+ case ETHTOOL_SRXCLSRLDEL:
1929
+ ret = cxgb4_ntuple_del_filter(dev, cmd);
1930
+ break;
1931
+ default:
1932
+ break;
1933
+ }
1934
+
1935
+ return ret;
12291936 }
12301937
12311938 static int set_dump(struct net_device *dev, struct ethtool_dump *eth_dump)
....@@ -1406,7 +2113,49 @@
14062113 return 0;
14072114 }
14082115
2116
+static void cxgb4_lb_test(struct net_device *netdev, u64 *lb_status)
2117
+{
2118
+ int dev_state = netif_running(netdev);
2119
+
2120
+ if (dev_state) {
2121
+ netif_tx_stop_all_queues(netdev);
2122
+ netif_carrier_off(netdev);
2123
+ }
2124
+
2125
+ *lb_status = cxgb4_selftest_lb_pkt(netdev);
2126
+
2127
+ if (dev_state) {
2128
+ netif_tx_start_all_queues(netdev);
2129
+ netif_carrier_on(netdev);
2130
+ }
2131
+}
2132
+
2133
+static void cxgb4_self_test(struct net_device *netdev,
2134
+ struct ethtool_test *eth_test, u64 *data)
2135
+{
2136
+ struct port_info *pi = netdev_priv(netdev);
2137
+ struct adapter *adap = pi->adapter;
2138
+
2139
+ memset(data, 0, sizeof(u64) * CXGB4_ETHTOOL_MAX_TEST);
2140
+
2141
+ if (!(adap->flags & CXGB4_FULL_INIT_DONE) ||
2142
+ !(adap->flags & CXGB4_FW_OK)) {
2143
+ eth_test->flags |= ETH_TEST_FL_FAILED;
2144
+ return;
2145
+ }
2146
+
2147
+ if (eth_test->flags & ETH_TEST_FL_OFFLINE)
2148
+ cxgb4_lb_test(netdev, &data[CXGB4_ETHTOOL_LB_TEST]);
2149
+
2150
+ if (data[CXGB4_ETHTOOL_LB_TEST])
2151
+ eth_test->flags |= ETH_TEST_FL_FAILED;
2152
+}
2153
+
14092154 static const struct ethtool_ops cxgb_ethtool_ops = {
2155
+ .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
2156
+ ETHTOOL_COALESCE_RX_MAX_FRAMES |
2157
+ ETHTOOL_COALESCE_TX_USECS_IRQ |
2158
+ ETHTOOL_COALESCE_USE_ADAPTIVE_RX,
14102159 .get_link_ksettings = get_link_ksettings,
14112160 .set_link_ksettings = set_link_ksettings,
14122161 .get_fecparam = get_fecparam,
....@@ -1432,9 +2181,11 @@
14322181 .get_regs_len = get_regs_len,
14332182 .get_regs = get_regs,
14342183 .get_rxnfc = get_rxnfc,
2184
+ .set_rxnfc = set_rxnfc,
14352185 .get_rxfh_indir_size = get_rss_table_size,
14362186 .get_rxfh = get_rss_table,
14372187 .set_rxfh = set_rss_table,
2188
+ .self_test = cxgb4_self_test,
14382189 .flash_device = set_flash,
14392190 .get_ts_info = get_ts_info,
14402191 .set_dump = set_dump,
....@@ -1446,6 +2197,87 @@
14462197 .set_priv_flags = cxgb4_set_priv_flags,
14472198 };
14482199
2200
+void cxgb4_cleanup_ethtool_filters(struct adapter *adap)
2201
+{
2202
+ struct cxgb4_ethtool_filter_info *eth_filter_info;
2203
+ u8 i;
2204
+
2205
+ if (!adap->ethtool_filters)
2206
+ return;
2207
+
2208
+ eth_filter_info = adap->ethtool_filters->port;
2209
+
2210
+ if (eth_filter_info) {
2211
+ for (i = 0; i < adap->params.nports; i++) {
2212
+ kvfree(eth_filter_info[i].loc_array);
2213
+ kfree(eth_filter_info[i].bmap);
2214
+ }
2215
+ kfree(eth_filter_info);
2216
+ }
2217
+
2218
+ kfree(adap->ethtool_filters);
2219
+}
2220
+
2221
+int cxgb4_init_ethtool_filters(struct adapter *adap)
2222
+{
2223
+ struct cxgb4_ethtool_filter_info *eth_filter_info;
2224
+ struct cxgb4_ethtool_filter *eth_filter;
2225
+ struct tid_info *tids = &adap->tids;
2226
+ u32 nentries, i;
2227
+ int ret;
2228
+
2229
+ eth_filter = kzalloc(sizeof(*eth_filter), GFP_KERNEL);
2230
+ if (!eth_filter)
2231
+ return -ENOMEM;
2232
+
2233
+ eth_filter_info = kcalloc(adap->params.nports,
2234
+ sizeof(*eth_filter_info),
2235
+ GFP_KERNEL);
2236
+ if (!eth_filter_info) {
2237
+ ret = -ENOMEM;
2238
+ goto free_eth_filter;
2239
+ }
2240
+
2241
+ eth_filter->port = eth_filter_info;
2242
+
2243
+ nentries = tids->nhpftids + tids->nftids;
2244
+ if (is_hashfilter(adap))
2245
+ nentries += tids->nhash +
2246
+ (adap->tids.stid_base - adap->tids.tid_base);
2247
+ eth_filter->nentries = nentries;
2248
+
2249
+ for (i = 0; i < adap->params.nports; i++) {
2250
+ eth_filter->port[i].loc_array = kvzalloc(nentries, GFP_KERNEL);
2251
+ if (!eth_filter->port[i].loc_array) {
2252
+ ret = -ENOMEM;
2253
+ goto free_eth_finfo;
2254
+ }
2255
+
2256
+ eth_filter->port[i].bmap = kcalloc(BITS_TO_LONGS(nentries),
2257
+ sizeof(unsigned long),
2258
+ GFP_KERNEL);
2259
+ if (!eth_filter->port[i].bmap) {
2260
+ ret = -ENOMEM;
2261
+ goto free_eth_finfo;
2262
+ }
2263
+ }
2264
+
2265
+ adap->ethtool_filters = eth_filter;
2266
+ return 0;
2267
+
2268
+free_eth_finfo:
2269
+ while (i-- > 0) {
2270
+ kfree(eth_filter->port[i].bmap);
2271
+ kvfree(eth_filter->port[i].loc_array);
2272
+ }
2273
+ kfree(eth_filter_info);
2274
+
2275
+free_eth_filter:
2276
+ kfree(eth_filter);
2277
+
2278
+ return ret;
2279
+}
2280
+
14492281 void cxgb4_set_ethtool_ops(struct net_device *netdev)
14502282 {
14512283 netdev->ethtool_ops = &cxgb_ethtool_ops;