1 /****************************************************************************
2 * Driver for Solarflare Solarstorm network controllers and boards
3 * Copyright 2005-2006 Fen Systems Ltd.
4 * Copyright 2006-2008 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"
17 #include "falcon_io.h"
19 /**************************************************************************
23 *************************************************************************/
25 static void falcon_reconfigure_gmac(struct efx_nic
*efx
)
27 bool loopback
, tx_fc
, rx_fc
, bytemode
;
29 unsigned int max_frame_len
;
32 /* Configuration register 1 */
33 tx_fc
= (efx
->link_fc
& EFX_FC_TX
) || !efx
->link_fd
;
34 rx_fc
= !!(efx
->link_fc
& EFX_FC_RX
);
35 loopback
= (efx
->loopback_mode
== LOOPBACK_GMAC
);
36 bytemode
= (efx
->link_speed
== 1000);
38 EFX_POPULATE_OWORD_5(reg
,
39 FRF_AB_GM_LOOP
, loopback
,
41 FRF_AB_GM_TX_FC_EN
, tx_fc
,
43 FRF_AB_GM_RX_FC_EN
, rx_fc
);
44 falcon_write(efx
, ®
, FR_AB_GM_CFG1
);
47 /* Configuration register 2 */
48 if_mode
= (bytemode
) ? 2 : 1;
49 EFX_POPULATE_OWORD_5(reg
,
50 FRF_AB_GM_IF_MODE
, if_mode
,
51 FRF_AB_GM_PAD_CRC_EN
, 1,
53 FRF_AB_GM_FD
, efx
->link_fd
,
54 FRF_AB_GM_PAMBL_LEN
, 0x7/*datasheet recommended */);
56 falcon_write(efx
, ®
, FR_AB_GM_CFG2
);
59 /* Max frame len register */
60 max_frame_len
= EFX_MAX_FRAME_LEN(efx
->net_dev
->mtu
);
61 EFX_POPULATE_OWORD_1(reg
, FRF_AB_GM_MAX_FLEN
, max_frame_len
);
62 falcon_write(efx
, ®
, FR_AB_GM_MAX_FLEN
);
65 /* FIFO configuration register 0 */
66 EFX_POPULATE_OWORD_5(reg
,
67 FRF_AB_GMF_FTFENREQ
, 1,
68 FRF_AB_GMF_STFENREQ
, 1,
69 FRF_AB_GMF_FRFENREQ
, 1,
70 FRF_AB_GMF_SRFENREQ
, 1,
71 FRF_AB_GMF_WTMENREQ
, 1);
72 falcon_write(efx
, ®
, FR_AB_GMF_CFG0
);
75 /* FIFO configuration register 1 */
76 EFX_POPULATE_OWORD_2(reg
,
77 FRF_AB_GMF_CFGFRTH
, 0x12,
78 FRF_AB_GMF_CFGXOFFRTX
, 0xffff);
79 falcon_write(efx
, ®
, FR_AB_GMF_CFG1
);
82 /* FIFO configuration register 2 */
83 EFX_POPULATE_OWORD_2(reg
,
84 FRF_AB_GMF_CFGHWM
, 0x3f,
85 FRF_AB_GMF_CFGLWM
, 0xa);
86 falcon_write(efx
, ®
, FR_AB_GMF_CFG2
);
89 /* FIFO configuration register 3 */
90 EFX_POPULATE_OWORD_2(reg
,
91 FRF_AB_GMF_CFGHWMFT
, 0x1c,
92 FRF_AB_GMF_CFGFTTH
, 0x08);
93 falcon_write(efx
, ®
, FR_AB_GMF_CFG3
);
96 /* FIFO configuration register 4 */
97 EFX_POPULATE_OWORD_1(reg
, FRF_AB_GMF_HSTFLTRFRM_PAUSE
, 1);
98 falcon_write(efx
, ®
, FR_AB_GMF_CFG4
);
101 /* FIFO configuration register 5 */
102 falcon_read(efx
, ®
, FR_AB_GMF_CFG5
);
103 EFX_SET_OWORD_FIELD(reg
, FRF_AB_GMF_CFGBYTMODE
, bytemode
);
104 EFX_SET_OWORD_FIELD(reg
, FRF_AB_GMF_CFGHDPLX
, !efx
->link_fd
);
105 EFX_SET_OWORD_FIELD(reg
, FRF_AB_GMF_HSTDRPLT64
, !efx
->link_fd
);
106 EFX_SET_OWORD_FIELD(reg
, FRF_AB_GMF_HSTFLTRFRMDC_PAUSE
, 0);
107 falcon_write(efx
, ®
, FR_AB_GMF_CFG5
);
111 EFX_POPULATE_OWORD_4(reg
,
112 FRF_AB_GM_ADR_B0
, efx
->net_dev
->dev_addr
[5],
113 FRF_AB_GM_ADR_B1
, efx
->net_dev
->dev_addr
[4],
114 FRF_AB_GM_ADR_B2
, efx
->net_dev
->dev_addr
[3],
115 FRF_AB_GM_ADR_B3
, efx
->net_dev
->dev_addr
[2]);
116 falcon_write(efx
, ®
, FR_AB_GM_ADR1
);
118 EFX_POPULATE_OWORD_2(reg
,
119 FRF_AB_GM_ADR_B4
, efx
->net_dev
->dev_addr
[1],
120 FRF_AB_GM_ADR_B5
, efx
->net_dev
->dev_addr
[0]);
121 falcon_write(efx
, ®
, FR_AB_GM_ADR2
);
124 falcon_reconfigure_mac_wrapper(efx
);
127 static void falcon_update_stats_gmac(struct efx_nic
*efx
)
129 struct efx_mac_stats
*mac_stats
= &efx
->mac_stats
;
130 unsigned long old_rx_pause
, old_tx_pause
;
131 unsigned long new_rx_pause
, new_tx_pause
;
134 rc
= falcon_dma_stats(efx
, GDmaDone_offset
);
138 /* Pause frames are erroneously counted as errors (SFC bug 3269) */
139 old_rx_pause
= mac_stats
->rx_pause
;
140 old_tx_pause
= mac_stats
->tx_pause
;
142 /* Update MAC stats from DMAed values */
143 FALCON_STAT(efx
, GRxGoodOct
, rx_good_bytes
);
144 FALCON_STAT(efx
, GRxBadOct
, rx_bad_bytes
);
145 FALCON_STAT(efx
, GRxMissPkt
, rx_missed
);
146 FALCON_STAT(efx
, GRxFalseCRS
, rx_false_carrier
);
147 FALCON_STAT(efx
, GRxPausePkt
, rx_pause
);
148 FALCON_STAT(efx
, GRxBadPkt
, rx_bad
);
149 FALCON_STAT(efx
, GRxUcastPkt
, rx_unicast
);
150 FALCON_STAT(efx
, GRxMcastPkt
, rx_multicast
);
151 FALCON_STAT(efx
, GRxBcastPkt
, rx_broadcast
);
152 FALCON_STAT(efx
, GRxGoodLt64Pkt
, rx_good_lt64
);
153 FALCON_STAT(efx
, GRxBadLt64Pkt
, rx_bad_lt64
);
154 FALCON_STAT(efx
, GRx64Pkt
, rx_64
);
155 FALCON_STAT(efx
, GRx65to127Pkt
, rx_65_to_127
);
156 FALCON_STAT(efx
, GRx128to255Pkt
, rx_128_to_255
);
157 FALCON_STAT(efx
, GRx256to511Pkt
, rx_256_to_511
);
158 FALCON_STAT(efx
, GRx512to1023Pkt
, rx_512_to_1023
);
159 FALCON_STAT(efx
, GRx1024to15xxPkt
, rx_1024_to_15xx
);
160 FALCON_STAT(efx
, GRx15xxtoJumboPkt
, rx_15xx_to_jumbo
);
161 FALCON_STAT(efx
, GRxGtJumboPkt
, rx_gtjumbo
);
162 FALCON_STAT(efx
, GRxFcsErr64to15xxPkt
, rx_bad_64_to_15xx
);
163 FALCON_STAT(efx
, GRxFcsErr15xxtoJumboPkt
, rx_bad_15xx_to_jumbo
);
164 FALCON_STAT(efx
, GRxFcsErrGtJumboPkt
, rx_bad_gtjumbo
);
165 FALCON_STAT(efx
, GTxGoodBadOct
, tx_bytes
);
166 FALCON_STAT(efx
, GTxGoodOct
, tx_good_bytes
);
167 FALCON_STAT(efx
, GTxSglColPkt
, tx_single_collision
);
168 FALCON_STAT(efx
, GTxMultColPkt
, tx_multiple_collision
);
169 FALCON_STAT(efx
, GTxExColPkt
, tx_excessive_collision
);
170 FALCON_STAT(efx
, GTxDefPkt
, tx_deferred
);
171 FALCON_STAT(efx
, GTxLateCol
, tx_late_collision
);
172 FALCON_STAT(efx
, GTxExDefPkt
, tx_excessive_deferred
);
173 FALCON_STAT(efx
, GTxPausePkt
, tx_pause
);
174 FALCON_STAT(efx
, GTxBadPkt
, tx_bad
);
175 FALCON_STAT(efx
, GTxUcastPkt
, tx_unicast
);
176 FALCON_STAT(efx
, GTxMcastPkt
, tx_multicast
);
177 FALCON_STAT(efx
, GTxBcastPkt
, tx_broadcast
);
178 FALCON_STAT(efx
, GTxLt64Pkt
, tx_lt64
);
179 FALCON_STAT(efx
, GTx64Pkt
, tx_64
);
180 FALCON_STAT(efx
, GTx65to127Pkt
, tx_65_to_127
);
181 FALCON_STAT(efx
, GTx128to255Pkt
, tx_128_to_255
);
182 FALCON_STAT(efx
, GTx256to511Pkt
, tx_256_to_511
);
183 FALCON_STAT(efx
, GTx512to1023Pkt
, tx_512_to_1023
);
184 FALCON_STAT(efx
, GTx1024to15xxPkt
, tx_1024_to_15xx
);
185 FALCON_STAT(efx
, GTx15xxtoJumboPkt
, tx_15xx_to_jumbo
);
186 FALCON_STAT(efx
, GTxGtJumboPkt
, tx_gtjumbo
);
187 FALCON_STAT(efx
, GTxNonTcpUdpPkt
, tx_non_tcpudp
);
188 FALCON_STAT(efx
, GTxMacSrcErrPkt
, tx_mac_src_error
);
189 FALCON_STAT(efx
, GTxIpSrcErrPkt
, tx_ip_src_error
);
191 /* Pause frames are erroneously counted as errors (SFC bug 3269) */
192 new_rx_pause
= mac_stats
->rx_pause
;
193 new_tx_pause
= mac_stats
->tx_pause
;
194 mac_stats
->rx_bad
-= (new_rx_pause
- old_rx_pause
);
195 mac_stats
->tx_bad
-= (new_tx_pause
- old_tx_pause
);
197 /* Derive stats that the MAC doesn't provide directly */
198 mac_stats
->tx_bad_bytes
=
199 mac_stats
->tx_bytes
- mac_stats
->tx_good_bytes
;
200 mac_stats
->tx_packets
=
201 mac_stats
->tx_lt64
+ mac_stats
->tx_64
+
202 mac_stats
->tx_65_to_127
+ mac_stats
->tx_128_to_255
+
203 mac_stats
->tx_256_to_511
+ mac_stats
->tx_512_to_1023
+
204 mac_stats
->tx_1024_to_15xx
+ mac_stats
->tx_15xx_to_jumbo
+
205 mac_stats
->tx_gtjumbo
;
206 mac_stats
->tx_collision
=
207 mac_stats
->tx_single_collision
+
208 mac_stats
->tx_multiple_collision
+
209 mac_stats
->tx_excessive_collision
+
210 mac_stats
->tx_late_collision
;
211 mac_stats
->rx_bytes
=
212 mac_stats
->rx_good_bytes
+ mac_stats
->rx_bad_bytes
;
213 mac_stats
->rx_packets
=
214 mac_stats
->rx_good_lt64
+ mac_stats
->rx_bad_lt64
+
215 mac_stats
->rx_64
+ mac_stats
->rx_65_to_127
+
216 mac_stats
->rx_128_to_255
+ mac_stats
->rx_256_to_511
+
217 mac_stats
->rx_512_to_1023
+ mac_stats
->rx_1024_to_15xx
+
218 mac_stats
->rx_15xx_to_jumbo
+ mac_stats
->rx_gtjumbo
;
219 mac_stats
->rx_good
= mac_stats
->rx_packets
- mac_stats
->rx_bad
;
220 mac_stats
->rx_lt64
= mac_stats
->rx_good_lt64
+ mac_stats
->rx_bad_lt64
;
223 struct efx_mac_operations falcon_gmac_operations
= {
224 .reconfigure
= falcon_reconfigure_gmac
,
225 .update_stats
= falcon_update_stats_gmac
,
226 .irq
= efx_port_dummy_op_void
,
227 .poll
= efx_port_dummy_op_void
,