1 /****************************************************************************
2 * Driver for Solarflare Solarstorm network controllers and boards
3 * Copyright 2005-2006 Fen Systems Ltd.
4 * Copyright 2006-2009 Solarflare Communications Inc.
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published
8 * by the Free Software Foundation, incorporated herein by reference.
11 #include <linux/delay.h>
12 #include "net_driver.h"
19 /**************************************************************************
23 *************************************************************************/
25 static int falcon_reconfigure_gmac(struct efx_nic
*efx
)
27 struct efx_link_state
*link_state
= &efx
->link_state
;
28 bool loopback
, tx_fc
, rx_fc
, bytemode
;
30 unsigned int max_frame_len
;
33 /* Configuration register 1 */
34 tx_fc
= (link_state
->fc
& EFX_FC_TX
) || !link_state
->fd
;
35 rx_fc
= !!(link_state
->fc
& EFX_FC_RX
);
36 loopback
= (efx
->loopback_mode
== LOOPBACK_GMAC
);
37 bytemode
= (link_state
->speed
== 1000);
39 EFX_POPULATE_OWORD_5(reg
,
40 FRF_AB_GM_LOOP
, loopback
,
42 FRF_AB_GM_TX_FC_EN
, tx_fc
,
44 FRF_AB_GM_RX_FC_EN
, rx_fc
);
45 efx_writeo(efx
, ®
, FR_AB_GM_CFG1
);
48 /* Configuration register 2 */
49 if_mode
= (bytemode
) ? 2 : 1;
50 EFX_POPULATE_OWORD_5(reg
,
51 FRF_AB_GM_IF_MODE
, if_mode
,
52 FRF_AB_GM_PAD_CRC_EN
, 1,
54 FRF_AB_GM_FD
, link_state
->fd
,
55 FRF_AB_GM_PAMBL_LEN
, 0x7/*datasheet recommended */);
57 efx_writeo(efx
, ®
, FR_AB_GM_CFG2
);
60 /* Max frame len register */
61 max_frame_len
= EFX_MAX_FRAME_LEN(efx
->net_dev
->mtu
);
62 EFX_POPULATE_OWORD_1(reg
, FRF_AB_GM_MAX_FLEN
, max_frame_len
);
63 efx_writeo(efx
, ®
, FR_AB_GM_MAX_FLEN
);
66 /* FIFO configuration register 0 */
67 EFX_POPULATE_OWORD_5(reg
,
68 FRF_AB_GMF_FTFENREQ
, 1,
69 FRF_AB_GMF_STFENREQ
, 1,
70 FRF_AB_GMF_FRFENREQ
, 1,
71 FRF_AB_GMF_SRFENREQ
, 1,
72 FRF_AB_GMF_WTMENREQ
, 1);
73 efx_writeo(efx
, ®
, FR_AB_GMF_CFG0
);
76 /* FIFO configuration register 1 */
77 EFX_POPULATE_OWORD_2(reg
,
78 FRF_AB_GMF_CFGFRTH
, 0x12,
79 FRF_AB_GMF_CFGXOFFRTX
, 0xffff);
80 efx_writeo(efx
, ®
, FR_AB_GMF_CFG1
);
83 /* FIFO configuration register 2 */
84 EFX_POPULATE_OWORD_2(reg
,
85 FRF_AB_GMF_CFGHWM
, 0x3f,
86 FRF_AB_GMF_CFGLWM
, 0xa);
87 efx_writeo(efx
, ®
, FR_AB_GMF_CFG2
);
90 /* FIFO configuration register 3 */
91 EFX_POPULATE_OWORD_2(reg
,
92 FRF_AB_GMF_CFGHWMFT
, 0x1c,
93 FRF_AB_GMF_CFGFTTH
, 0x08);
94 efx_writeo(efx
, ®
, FR_AB_GMF_CFG3
);
97 /* FIFO configuration register 4 */
98 EFX_POPULATE_OWORD_1(reg
, FRF_AB_GMF_HSTFLTRFRM_PAUSE
, 1);
99 efx_writeo(efx
, ®
, FR_AB_GMF_CFG4
);
102 /* FIFO configuration register 5 */
103 efx_reado(efx
, ®
, FR_AB_GMF_CFG5
);
104 EFX_SET_OWORD_FIELD(reg
, FRF_AB_GMF_CFGBYTMODE
, bytemode
);
105 EFX_SET_OWORD_FIELD(reg
, FRF_AB_GMF_CFGHDPLX
, !link_state
->fd
);
106 EFX_SET_OWORD_FIELD(reg
, FRF_AB_GMF_HSTDRPLT64
, !link_state
->fd
);
107 EFX_SET_OWORD_FIELD(reg
, FRF_AB_GMF_HSTFLTRFRMDC_PAUSE
, 0);
108 efx_writeo(efx
, ®
, FR_AB_GMF_CFG5
);
112 EFX_POPULATE_OWORD_4(reg
,
113 FRF_AB_GM_ADR_B0
, efx
->net_dev
->dev_addr
[5],
114 FRF_AB_GM_ADR_B1
, efx
->net_dev
->dev_addr
[4],
115 FRF_AB_GM_ADR_B2
, efx
->net_dev
->dev_addr
[3],
116 FRF_AB_GM_ADR_B3
, efx
->net_dev
->dev_addr
[2]);
117 efx_writeo(efx
, ®
, FR_AB_GM_ADR1
);
119 EFX_POPULATE_OWORD_2(reg
,
120 FRF_AB_GM_ADR_B4
, efx
->net_dev
->dev_addr
[1],
121 FRF_AB_GM_ADR_B5
, efx
->net_dev
->dev_addr
[0]);
122 efx_writeo(efx
, ®
, FR_AB_GM_ADR2
);
125 falcon_reconfigure_mac_wrapper(efx
);
130 static void falcon_update_stats_gmac(struct efx_nic
*efx
)
132 struct efx_mac_stats
*mac_stats
= &efx
->mac_stats
;
133 unsigned long old_rx_pause
, old_tx_pause
;
134 unsigned long new_rx_pause
, new_tx_pause
;
136 /* Pause frames are erroneously counted as errors (SFC bug 3269) */
137 old_rx_pause
= mac_stats
->rx_pause
;
138 old_tx_pause
= mac_stats
->tx_pause
;
140 /* Update MAC stats from DMAed values */
141 FALCON_STAT(efx
, GRxGoodOct
, rx_good_bytes
);
142 FALCON_STAT(efx
, GRxBadOct
, rx_bad_bytes
);
143 FALCON_STAT(efx
, GRxMissPkt
, rx_missed
);
144 FALCON_STAT(efx
, GRxFalseCRS
, rx_false_carrier
);
145 FALCON_STAT(efx
, GRxPausePkt
, rx_pause
);
146 FALCON_STAT(efx
, GRxBadPkt
, rx_bad
);
147 FALCON_STAT(efx
, GRxUcastPkt
, rx_unicast
);
148 FALCON_STAT(efx
, GRxMcastPkt
, rx_multicast
);
149 FALCON_STAT(efx
, GRxBcastPkt
, rx_broadcast
);
150 FALCON_STAT(efx
, GRxGoodLt64Pkt
, rx_good_lt64
);
151 FALCON_STAT(efx
, GRxBadLt64Pkt
, rx_bad_lt64
);
152 FALCON_STAT(efx
, GRx64Pkt
, rx_64
);
153 FALCON_STAT(efx
, GRx65to127Pkt
, rx_65_to_127
);
154 FALCON_STAT(efx
, GRx128to255Pkt
, rx_128_to_255
);
155 FALCON_STAT(efx
, GRx256to511Pkt
, rx_256_to_511
);
156 FALCON_STAT(efx
, GRx512to1023Pkt
, rx_512_to_1023
);
157 FALCON_STAT(efx
, GRx1024to15xxPkt
, rx_1024_to_15xx
);
158 FALCON_STAT(efx
, GRx15xxtoJumboPkt
, rx_15xx_to_jumbo
);
159 FALCON_STAT(efx
, GRxGtJumboPkt
, rx_gtjumbo
);
160 FALCON_STAT(efx
, GRxFcsErr64to15xxPkt
, rx_bad_64_to_15xx
);
161 FALCON_STAT(efx
, GRxFcsErr15xxtoJumboPkt
, rx_bad_15xx_to_jumbo
);
162 FALCON_STAT(efx
, GRxFcsErrGtJumboPkt
, rx_bad_gtjumbo
);
163 FALCON_STAT(efx
, GTxGoodBadOct
, tx_bytes
);
164 FALCON_STAT(efx
, GTxGoodOct
, tx_good_bytes
);
165 FALCON_STAT(efx
, GTxSglColPkt
, tx_single_collision
);
166 FALCON_STAT(efx
, GTxMultColPkt
, tx_multiple_collision
);
167 FALCON_STAT(efx
, GTxExColPkt
, tx_excessive_collision
);
168 FALCON_STAT(efx
, GTxDefPkt
, tx_deferred
);
169 FALCON_STAT(efx
, GTxLateCol
, tx_late_collision
);
170 FALCON_STAT(efx
, GTxExDefPkt
, tx_excessive_deferred
);
171 FALCON_STAT(efx
, GTxPausePkt
, tx_pause
);
172 FALCON_STAT(efx
, GTxBadPkt
, tx_bad
);
173 FALCON_STAT(efx
, GTxUcastPkt
, tx_unicast
);
174 FALCON_STAT(efx
, GTxMcastPkt
, tx_multicast
);
175 FALCON_STAT(efx
, GTxBcastPkt
, tx_broadcast
);
176 FALCON_STAT(efx
, GTxLt64Pkt
, tx_lt64
);
177 FALCON_STAT(efx
, GTx64Pkt
, tx_64
);
178 FALCON_STAT(efx
, GTx65to127Pkt
, tx_65_to_127
);
179 FALCON_STAT(efx
, GTx128to255Pkt
, tx_128_to_255
);
180 FALCON_STAT(efx
, GTx256to511Pkt
, tx_256_to_511
);
181 FALCON_STAT(efx
, GTx512to1023Pkt
, tx_512_to_1023
);
182 FALCON_STAT(efx
, GTx1024to15xxPkt
, tx_1024_to_15xx
);
183 FALCON_STAT(efx
, GTx15xxtoJumboPkt
, tx_15xx_to_jumbo
);
184 FALCON_STAT(efx
, GTxGtJumboPkt
, tx_gtjumbo
);
185 FALCON_STAT(efx
, GTxNonTcpUdpPkt
, tx_non_tcpudp
);
186 FALCON_STAT(efx
, GTxMacSrcErrPkt
, tx_mac_src_error
);
187 FALCON_STAT(efx
, GTxIpSrcErrPkt
, tx_ip_src_error
);
189 /* Pause frames are erroneously counted as errors (SFC bug 3269) */
190 new_rx_pause
= mac_stats
->rx_pause
;
191 new_tx_pause
= mac_stats
->tx_pause
;
192 mac_stats
->rx_bad
-= (new_rx_pause
- old_rx_pause
);
193 mac_stats
->tx_bad
-= (new_tx_pause
- old_tx_pause
);
195 /* Derive stats that the MAC doesn't provide directly */
196 mac_stats
->tx_bad_bytes
=
197 mac_stats
->tx_bytes
- mac_stats
->tx_good_bytes
;
198 mac_stats
->tx_packets
=
199 mac_stats
->tx_lt64
+ mac_stats
->tx_64
+
200 mac_stats
->tx_65_to_127
+ mac_stats
->tx_128_to_255
+
201 mac_stats
->tx_256_to_511
+ mac_stats
->tx_512_to_1023
+
202 mac_stats
->tx_1024_to_15xx
+ mac_stats
->tx_15xx_to_jumbo
+
203 mac_stats
->tx_gtjumbo
;
204 mac_stats
->tx_collision
=
205 mac_stats
->tx_single_collision
+
206 mac_stats
->tx_multiple_collision
+
207 mac_stats
->tx_excessive_collision
+
208 mac_stats
->tx_late_collision
;
209 mac_stats
->rx_bytes
=
210 mac_stats
->rx_good_bytes
+ mac_stats
->rx_bad_bytes
;
211 mac_stats
->rx_packets
=
212 mac_stats
->rx_good_lt64
+ mac_stats
->rx_bad_lt64
+
213 mac_stats
->rx_64
+ mac_stats
->rx_65_to_127
+
214 mac_stats
->rx_128_to_255
+ mac_stats
->rx_256_to_511
+
215 mac_stats
->rx_512_to_1023
+ mac_stats
->rx_1024_to_15xx
+
216 mac_stats
->rx_15xx_to_jumbo
+ mac_stats
->rx_gtjumbo
;
217 mac_stats
->rx_good
= mac_stats
->rx_packets
- mac_stats
->rx_bad
;
218 mac_stats
->rx_lt64
= mac_stats
->rx_good_lt64
+ mac_stats
->rx_bad_lt64
;
221 static bool falcon_gmac_check_fault(struct efx_nic
*efx
)
226 struct efx_mac_operations falcon_gmac_operations
= {
227 .reconfigure
= falcon_reconfigure_gmac
,
228 .update_stats
= falcon_update_stats_gmac
,
229 .check_fault
= falcon_gmac_check_fault
,