@@ -59,6 +59,16 @@ static const struct hns3_stats hns3_rxq_stats[] = {
59
59
60
60
#define HNS3_TQP_STATS_COUNT (HNS3_TXQ_STATS_COUNT + HNS3_RXQ_STATS_COUNT)
61
61
62
+ #define HNS3_SELF_TEST_TPYE_NUM 1
63
+ #define HNS3_NIC_LB_TEST_PKT_NUM 1
64
+ #define HNS3_NIC_LB_TEST_RING_ID 0
65
+ #define HNS3_NIC_LB_TEST_PACKET_SIZE 128
66
+
67
+ /* Nic loopback test err */
68
+ #define HNS3_NIC_LB_TEST_NO_MEM_ERR 1
69
+ #define HNS3_NIC_LB_TEST_TX_CNT_ERR 2
70
+ #define HNS3_NIC_LB_TEST_RX_CNT_ERR 3
71
+
62
72
struct hns3_link_mode_mapping {
63
73
u32 hns3_link_mode ;
64
74
u32 ethtool_link_mode ;
@@ -77,6 +87,268 @@ static const struct hns3_link_mode_mapping hns3_lm_map[] = {
77
87
{HNS3_LM_1000BASET_FULL_BIT , ETHTOOL_LINK_MODE_1000baseT_Full_BIT },
78
88
};
79
89
90
+ static int hns3_lp_setup (struct net_device * ndev , enum hnae3_loop loop )
91
+ {
92
+ struct hnae3_handle * h = hns3_get_handle (ndev );
93
+ int ret ;
94
+
95
+ if (!h -> ae_algo -> ops -> set_loopback ||
96
+ !h -> ae_algo -> ops -> set_promisc_mode )
97
+ return - EOPNOTSUPP ;
98
+
99
+ switch (loop ) {
100
+ case HNAE3_MAC_INTER_LOOP_MAC :
101
+ ret = h -> ae_algo -> ops -> set_loopback (h , loop , true);
102
+ break ;
103
+ case HNAE3_MAC_LOOP_NONE :
104
+ ret = h -> ae_algo -> ops -> set_loopback (h ,
105
+ HNAE3_MAC_INTER_LOOP_MAC , false);
106
+ break ;
107
+ default :
108
+ ret = - ENOTSUPP ;
109
+ break ;
110
+ }
111
+
112
+ if (ret )
113
+ return ret ;
114
+
115
+ if (loop == HNAE3_MAC_LOOP_NONE )
116
+ h -> ae_algo -> ops -> set_promisc_mode (h , ndev -> flags & IFF_PROMISC );
117
+ else
118
+ h -> ae_algo -> ops -> set_promisc_mode (h , 1 );
119
+
120
+ return ret ;
121
+ }
122
+
123
+ static int hns3_lp_up (struct net_device * ndev , enum hnae3_loop loop_mode )
124
+ {
125
+ struct hnae3_handle * h = hns3_get_handle (ndev );
126
+ int ret ;
127
+
128
+ if (!h -> ae_algo -> ops -> start )
129
+ return - EOPNOTSUPP ;
130
+
131
+ ret = h -> ae_algo -> ops -> start (h );
132
+ if (ret ) {
133
+ netdev_err (ndev ,
134
+ "hns3_lb_up ae start return error: %d\n" , ret );
135
+ return ret ;
136
+ }
137
+
138
+ ret = hns3_lp_setup (ndev , loop_mode );
139
+ usleep_range (10000 , 20000 );
140
+
141
+ return ret ;
142
+ }
143
+
144
+ static int hns3_lp_down (struct net_device * ndev )
145
+ {
146
+ struct hnae3_handle * h = hns3_get_handle (ndev );
147
+ int ret ;
148
+
149
+ if (!h -> ae_algo -> ops -> stop )
150
+ return - EOPNOTSUPP ;
151
+
152
+ ret = hns3_lp_setup (ndev , HNAE3_MAC_LOOP_NONE );
153
+ if (ret ) {
154
+ netdev_err (ndev , "lb_setup return error: %d\n" , ret );
155
+ return ret ;
156
+ }
157
+
158
+ h -> ae_algo -> ops -> stop (h );
159
+ usleep_range (10000 , 20000 );
160
+
161
+ return 0 ;
162
+ }
163
+
164
+ static void hns3_lp_setup_skb (struct sk_buff * skb )
165
+ {
166
+ struct net_device * ndev = skb -> dev ;
167
+ unsigned char * packet ;
168
+ struct ethhdr * ethh ;
169
+ unsigned int i ;
170
+
171
+ skb_reserve (skb , NET_IP_ALIGN );
172
+ ethh = skb_put (skb , sizeof (struct ethhdr ));
173
+ packet = skb_put (skb , HNS3_NIC_LB_TEST_PACKET_SIZE );
174
+
175
+ memcpy (ethh -> h_dest , ndev -> dev_addr , ETH_ALEN );
176
+ eth_zero_addr (ethh -> h_source );
177
+ ethh -> h_proto = htons (ETH_P_ARP );
178
+ skb_reset_mac_header (skb );
179
+
180
+ for (i = 0 ; i < HNS3_NIC_LB_TEST_PACKET_SIZE ; i ++ )
181
+ packet [i ] = (unsigned char )(i & 0xff );
182
+ }
183
+
184
+ static void hns3_lb_check_skb_data (struct hns3_enet_ring * ring ,
185
+ struct sk_buff * skb )
186
+ {
187
+ struct hns3_enet_tqp_vector * tqp_vector = ring -> tqp_vector ;
188
+ unsigned char * packet = skb -> data ;
189
+ u32 i ;
190
+
191
+ for (i = 0 ; i < skb -> len ; i ++ )
192
+ if (packet [i ] != (unsigned char )(i & 0xff ))
193
+ break ;
194
+
195
+ /* The packet is correctly received */
196
+ if (i == skb -> len )
197
+ tqp_vector -> rx_group .total_packets ++ ;
198
+ else
199
+ print_hex_dump (KERN_ERR , "selftest:" , DUMP_PREFIX_OFFSET , 16 , 1 ,
200
+ skb -> data , skb -> len , true);
201
+
202
+ dev_kfree_skb_any (skb );
203
+ }
204
+
205
+ static u32 hns3_lb_check_rx_ring (struct hns3_nic_priv * priv , u32 budget )
206
+ {
207
+ struct hnae3_handle * h = priv -> ae_handle ;
208
+ struct hnae3_knic_private_info * kinfo ;
209
+ u32 i , rcv_good_pkt_total = 0 ;
210
+
211
+ kinfo = & h -> kinfo ;
212
+ for (i = kinfo -> num_tqps ; i < kinfo -> num_tqps * 2 ; i ++ ) {
213
+ struct hns3_enet_ring * ring = priv -> ring_data [i ].ring ;
214
+ struct hns3_enet_ring_group * rx_group ;
215
+ u64 pre_rx_pkt ;
216
+
217
+ rx_group = & ring -> tqp_vector -> rx_group ;
218
+ pre_rx_pkt = rx_group -> total_packets ;
219
+
220
+ hns3_clean_rx_ring (ring , budget , hns3_lb_check_skb_data );
221
+
222
+ rcv_good_pkt_total += (rx_group -> total_packets - pre_rx_pkt );
223
+ rx_group -> total_packets = pre_rx_pkt ;
224
+ }
225
+ return rcv_good_pkt_total ;
226
+ }
227
+
228
+ static void hns3_lb_clear_tx_ring (struct hns3_nic_priv * priv , u32 start_ringid ,
229
+ u32 end_ringid , u32 budget )
230
+ {
231
+ u32 i ;
232
+
233
+ for (i = start_ringid ; i <= end_ringid ; i ++ ) {
234
+ struct hns3_enet_ring * ring = priv -> ring_data [i ].ring ;
235
+
236
+ hns3_clean_tx_ring (ring , budget );
237
+ }
238
+ }
239
+
240
+ /**
241
+ * hns3_lp_run_test - run loopback test
242
+ * @ndev: net device
243
+ * @mode: loopback type
244
+ */
245
+ static int hns3_lp_run_test (struct net_device * ndev , enum hnae3_loop mode )
246
+ {
247
+ struct hns3_nic_priv * priv = netdev_priv (ndev );
248
+ struct sk_buff * skb ;
249
+ u32 i , good_cnt ;
250
+ int ret_val = 0 ;
251
+
252
+ skb = alloc_skb (HNS3_NIC_LB_TEST_PACKET_SIZE + ETH_HLEN + NET_IP_ALIGN ,
253
+ GFP_KERNEL );
254
+ if (!skb )
255
+ return HNS3_NIC_LB_TEST_NO_MEM_ERR ;
256
+
257
+ skb -> dev = ndev ;
258
+ hns3_lp_setup_skb (skb );
259
+ skb -> queue_mapping = HNS3_NIC_LB_TEST_RING_ID ;
260
+
261
+ good_cnt = 0 ;
262
+ for (i = 0 ; i < HNS3_NIC_LB_TEST_PKT_NUM ; i ++ ) {
263
+ netdev_tx_t tx_ret ;
264
+
265
+ skb_get (skb );
266
+ tx_ret = hns3_nic_net_xmit (skb , ndev );
267
+ if (tx_ret == NETDEV_TX_OK )
268
+ good_cnt ++ ;
269
+ else
270
+ netdev_err (ndev , "hns3_lb_run_test xmit failed: %d\n" ,
271
+ tx_ret );
272
+ }
273
+ if (good_cnt != HNS3_NIC_LB_TEST_PKT_NUM ) {
274
+ ret_val = HNS3_NIC_LB_TEST_TX_CNT_ERR ;
275
+ netdev_err (ndev , "mode %d sent fail, cnt=0x%x, budget=0x%x\n" ,
276
+ mode , good_cnt , HNS3_NIC_LB_TEST_PKT_NUM );
277
+ goto out ;
278
+ }
279
+
280
+ /* Allow 200 milliseconds for packets to go from Tx to Rx */
281
+ msleep (200 );
282
+
283
+ good_cnt = hns3_lb_check_rx_ring (priv , HNS3_NIC_LB_TEST_PKT_NUM );
284
+ if (good_cnt != HNS3_NIC_LB_TEST_PKT_NUM ) {
285
+ ret_val = HNS3_NIC_LB_TEST_RX_CNT_ERR ;
286
+ netdev_err (ndev , "mode %d recv fail, cnt=0x%x, budget=0x%x\n" ,
287
+ mode , good_cnt , HNS3_NIC_LB_TEST_PKT_NUM );
288
+ }
289
+
290
+ out :
291
+ hns3_lb_clear_tx_ring (priv , HNS3_NIC_LB_TEST_RING_ID ,
292
+ HNS3_NIC_LB_TEST_RING_ID ,
293
+ HNS3_NIC_LB_TEST_PKT_NUM );
294
+
295
+ kfree_skb (skb );
296
+ return ret_val ;
297
+ }
298
+
299
+ /**
300
+ * hns3_nic_self_test - self test
301
+ * @ndev: net device
302
+ * @eth_test: test cmd
303
+ * @data: test result
304
+ */
305
+ static void hns3_self_test (struct net_device * ndev ,
306
+ struct ethtool_test * eth_test , u64 * data )
307
+ {
308
+ struct hns3_nic_priv * priv = netdev_priv (ndev );
309
+ struct hnae3_handle * h = priv -> ae_handle ;
310
+ int st_param [HNS3_SELF_TEST_TPYE_NUM ][2 ];
311
+ bool if_running = netif_running (ndev );
312
+ int test_index = 0 ;
313
+ u32 i ;
314
+
315
+ /* Only do offline selftest, or pass by default */
316
+ if (eth_test -> flags != ETH_TEST_FL_OFFLINE )
317
+ return ;
318
+
319
+ st_param [HNAE3_MAC_INTER_LOOP_MAC ][0 ] = HNAE3_MAC_INTER_LOOP_MAC ;
320
+ st_param [HNAE3_MAC_INTER_LOOP_MAC ][1 ] =
321
+ h -> flags & HNAE3_SUPPORT_MAC_LOOPBACK ;
322
+
323
+ if (if_running )
324
+ dev_close (ndev );
325
+
326
+ set_bit (HNS3_NIC_STATE_TESTING , & priv -> state );
327
+
328
+ for (i = 0 ; i < HNS3_SELF_TEST_TPYE_NUM ; i ++ ) {
329
+ enum hnae3_loop loop_type = (enum hnae3_loop )st_param [i ][0 ];
330
+
331
+ if (!st_param [i ][1 ])
332
+ continue ;
333
+
334
+ data [test_index ] = hns3_lp_up (ndev , loop_type );
335
+ if (!data [test_index ]) {
336
+ data [test_index ] = hns3_lp_run_test (ndev , loop_type );
337
+ hns3_lp_down (ndev );
338
+ }
339
+
340
+ if (data [test_index ])
341
+ eth_test -> flags |= ETH_TEST_FL_FAILED ;
342
+
343
+ test_index ++ ;
344
+ }
345
+
346
+ clear_bit (HNS3_NIC_STATE_TESTING , & priv -> state );
347
+
348
+ if (if_running )
349
+ dev_open (ndev );
350
+ }
351
+
80
352
static void hns3_driv_to_eth_caps (u32 caps , struct ethtool_link_ksettings * cmd ,
81
353
bool is_advertised )
82
354
{
@@ -553,6 +825,7 @@ static int hns3_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd)
553
825
}
554
826
555
827
static const struct ethtool_ops hns3_ethtool_ops = {
828
+ .self_test = hns3_self_test ,
556
829
.get_drvinfo = hns3_get_drvinfo ,
557
830
.get_link = hns3_get_link ,
558
831
.get_ringparam = hns3_get_ringparam ,
0 commit comments