diff options
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4/Makefile | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 47 | ||||
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c | 915 | ||||
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 1618 | ||||
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 728 |
5 files changed, 1702 insertions, 1608 deletions
diff --git a/drivers/net/ethernet/chelsio/cxgb4/Makefile b/drivers/net/ethernet/chelsio/cxgb4/Makefile index 07d9b68a4da2..ace0ab98d0f1 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/Makefile +++ b/drivers/net/ethernet/chelsio/cxgb4/Makefile | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | obj-$(CONFIG_CHELSIO_T4) += cxgb4.o | 5 | obj-$(CONFIG_CHELSIO_T4) += cxgb4.o |
6 | 6 | ||
7 | cxgb4-objs := cxgb4_main.o l2t.o t4_hw.o sge.o clip_tbl.o | 7 | cxgb4-objs := cxgb4_main.o l2t.o t4_hw.o sge.o clip_tbl.o cxgb4_ethtool.o |
8 | cxgb4-$(CONFIG_CHELSIO_T4_DCB) += cxgb4_dcb.o | 8 | cxgb4-$(CONFIG_CHELSIO_T4_DCB) += cxgb4_dcb.o |
9 | cxgb4-$(CONFIG_CHELSIO_T4_FCOE) += cxgb4_fcoe.o | 9 | cxgb4-$(CONFIG_CHELSIO_T4_FCOE) += cxgb4_fcoe.o |
10 | cxgb4-$(CONFIG_DEBUG_FS) += cxgb4_debugfs.o | 10 | cxgb4-$(CONFIG_DEBUG_FS) += cxgb4_debugfs.o |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index 6c80eb2e61f4..524d11098c56 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | |||
@@ -60,6 +60,11 @@ enum { | |||
60 | }; | 60 | }; |
61 | 61 | ||
62 | enum { | 62 | enum { |
63 | T4_REGMAP_SIZE = (160 * 1024), | ||
64 | T5_REGMAP_SIZE = (332 * 1024), | ||
65 | }; | ||
66 | |||
67 | enum { | ||
63 | MEM_EDC0, | 68 | MEM_EDC0, |
64 | MEM_EDC1, | 69 | MEM_EDC1, |
65 | MEM_MC, | 70 | MEM_MC, |
@@ -374,6 +379,17 @@ enum { | |||
374 | }; | 379 | }; |
375 | 380 | ||
376 | enum { | 381 | enum { |
382 | MAX_TXQ_ENTRIES = 16384, | ||
383 | MAX_CTRL_TXQ_ENTRIES = 1024, | ||
384 | MAX_RSPQ_ENTRIES = 16384, | ||
385 | MAX_RX_BUFFERS = 16384, | ||
386 | MIN_TXQ_ENTRIES = 32, | ||
387 | MIN_CTRL_TXQ_ENTRIES = 32, | ||
388 | MIN_RSPQ_ENTRIES = 128, | ||
389 | MIN_FL_ENTRIES = 16 | ||
390 | }; | ||
391 | |||
392 | enum { | ||
377 | INGQ_EXTRAS = 2, /* firmware event queue and */ | 393 | INGQ_EXTRAS = 2, /* firmware event queue and */ |
378 | /* forwarded interrupts */ | 394 | /* forwarded interrupts */ |
379 | MAX_INGQ = MAX_ETH_QSETS + MAX_OFLD_QSETS + MAX_RDMA_QUEUES | 395 | MAX_INGQ = MAX_ETH_QSETS + MAX_OFLD_QSETS + MAX_RDMA_QUEUES |
@@ -1000,6 +1016,30 @@ static inline bool cxgb_poll_busy_polling(struct sge_rspq *q) | |||
1000 | } | 1016 | } |
1001 | #endif /* CONFIG_NET_RX_BUSY_POLL */ | 1017 | #endif /* CONFIG_NET_RX_BUSY_POLL */ |
1002 | 1018 | ||
1019 | /* Return a version number to identify the type of adapter. The scheme is: | ||
1020 | * - bits 0..9: chip version | ||
1021 | * - bits 10..15: chip revision | ||
1022 | * - bits 16..23: register dump version | ||
1023 | */ | ||
1024 | static inline unsigned int mk_adap_vers(struct adapter *ap) | ||
1025 | { | ||
1026 | return CHELSIO_CHIP_VERSION(ap->params.chip) | | ||
1027 | (CHELSIO_CHIP_RELEASE(ap->params.chip) << 10) | (1 << 16); | ||
1028 | } | ||
1029 | |||
1030 | /* Return a queue's interrupt hold-off time in us. 0 means no timer. */ | ||
1031 | static inline unsigned int qtimer_val(const struct adapter *adap, | ||
1032 | const struct sge_rspq *q) | ||
1033 | { | ||
1034 | unsigned int idx = q->intr_params >> 1; | ||
1035 | |||
1036 | return idx < SGE_NTIMERS ? adap->sge.timer_val[idx] : 0; | ||
1037 | } | ||
1038 | |||
1039 | /* driver version & name used for ethtool_drvinfo */ | ||
1040 | extern char cxgb4_driver_name[]; | ||
1041 | extern const char cxgb4_driver_version[]; | ||
1042 | |||
1003 | void t4_os_portmod_changed(const struct adapter *adap, int port_id); | 1043 | void t4_os_portmod_changed(const struct adapter *adap, int port_id); |
1004 | void t4_os_link_changed(struct adapter *adap, int port_id, int link_stat); | 1044 | void t4_os_link_changed(struct adapter *adap, int port_id, int link_stat); |
1005 | 1045 | ||
@@ -1029,6 +1069,10 @@ int t4_sge_init(struct adapter *adap); | |||
1029 | void t4_sge_start(struct adapter *adap); | 1069 | void t4_sge_start(struct adapter *adap); |
1030 | void t4_sge_stop(struct adapter *adap); | 1070 | void t4_sge_stop(struct adapter *adap); |
1031 | int cxgb_busy_poll(struct napi_struct *napi); | 1071 | int cxgb_busy_poll(struct napi_struct *napi); |
1072 | int cxgb4_set_rspq_intr_params(struct sge_rspq *q, unsigned int us, | ||
1073 | unsigned int cnt); | ||
1074 | void cxgb4_set_ethtool_ops(struct net_device *netdev); | ||
1075 | int cxgb4_write_rss(const struct port_info *pi, const u16 *queues); | ||
1032 | extern int dbfifo_int_thresh; | 1076 | extern int dbfifo_int_thresh; |
1033 | 1077 | ||
1034 | #define for_each_port(adapter, iter) \ | 1078 | #define for_each_port(adapter, iter) \ |
@@ -1117,6 +1161,9 @@ static inline int t4_memory_write(struct adapter *adap, int mtype, u32 addr, | |||
1117 | return t4_memory_rw(adap, 0, mtype, addr, len, buf, 0); | 1161 | return t4_memory_rw(adap, 0, mtype, addr, len, buf, 0); |
1118 | } | 1162 | } |
1119 | 1163 | ||
1164 | unsigned int t4_get_regs_len(struct adapter *adapter); | ||
1165 | void t4_get_regs(struct adapter *adap, void *buf, size_t buf_size); | ||
1166 | |||
1120 | int t4_seeprom_wp(struct adapter *adapter, bool enable); | 1167 | int t4_seeprom_wp(struct adapter *adapter, bool enable); |
1121 | int get_vpd_params(struct adapter *adapter, struct vpd_params *p); | 1168 | int get_vpd_params(struct adapter *adapter, struct vpd_params *p); |
1122 | int t4_read_flash(struct adapter *adapter, unsigned int addr, | 1169 | int t4_read_flash(struct adapter *adapter, unsigned int addr, |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c new file mode 100644 index 000000000000..10d82b51d7ef --- /dev/null +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c | |||
@@ -0,0 +1,915 @@ | |||
1 | /* | ||
2 | * 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 | * | ||
16 | */ | ||
17 | |||
18 | #include <linux/firmware.h> | ||
19 | #include <linux/mdio.h> | ||
20 | |||
21 | #include "cxgb4.h" | ||
22 | #include "t4_regs.h" | ||
23 | #include "t4fw_api.h" | ||
24 | |||
25 | #define EEPROM_MAGIC 0x38E2F10C | ||
26 | |||
27 | static u32 get_msglevel(struct net_device *dev) | ||
28 | { | ||
29 | return netdev2adap(dev)->msg_enable; | ||
30 | } | ||
31 | |||
32 | static void set_msglevel(struct net_device *dev, u32 val) | ||
33 | { | ||
34 | netdev2adap(dev)->msg_enable = val; | ||
35 | } | ||
36 | |||
37 | static const char stats_strings[][ETH_GSTRING_LEN] = { | ||
38 | "TxOctetsOK ", | ||
39 | "TxFramesOK ", | ||
40 | "TxBroadcastFrames ", | ||
41 | "TxMulticastFrames ", | ||
42 | "TxUnicastFrames ", | ||
43 | "TxErrorFrames ", | ||
44 | |||
45 | "TxFrames64 ", | ||
46 | "TxFrames65To127 ", | ||
47 | "TxFrames128To255 ", | ||
48 | "TxFrames256To511 ", | ||
49 | "TxFrames512To1023 ", | ||
50 | "TxFrames1024To1518 ", | ||
51 | "TxFrames1519ToMax ", | ||
52 | |||
53 | "TxFramesDropped ", | ||
54 | "TxPauseFrames ", | ||
55 | "TxPPP0Frames ", | ||
56 | "TxPPP1Frames ", | ||
57 | "TxPPP2Frames ", | ||
58 | "TxPPP3Frames ", | ||
59 | "TxPPP4Frames ", | ||
60 | "TxPPP5Frames ", | ||
61 | "TxPPP6Frames ", | ||
62 | "TxPPP7Frames ", | ||
63 | |||
64 | "RxOctetsOK ", | ||
65 | "RxFramesOK ", | ||
66 | "RxBroadcastFrames ", | ||
67 | "RxMulticastFrames ", | ||
68 | "RxUnicastFrames ", | ||
69 | |||
70 | "RxFramesTooLong ", | ||
71 | "RxJabberErrors ", | ||
72 | "RxFCSErrors ", | ||
73 | "RxLengthErrors ", | ||
74 | "RxSymbolErrors ", | ||
75 | "RxRuntFrames ", | ||
76 | |||
77 | "RxFrames64 ", | ||
78 | "RxFrames65To127 ", | ||
79 | "RxFrames128To255 ", | ||
80 | "RxFrames256To511 ", | ||
81 | "RxFrames512To1023 ", | ||
82 | "RxFrames1024To1518 ", | ||
83 | "RxFrames1519ToMax ", | ||
84 | |||
85 | "RxPauseFrames ", | ||
86 | "RxPPP0Frames ", | ||
87 | "RxPPP1Frames ", | ||
88 | "RxPPP2Frames ", | ||
89 | "RxPPP3Frames ", | ||
90 | "RxPPP4Frames ", | ||
91 | "RxPPP5Frames ", | ||
92 | "RxPPP6Frames ", | ||
93 | "RxPPP7Frames ", | ||
94 | |||
95 | "RxBG0FramesDropped ", | ||
96 | "RxBG1FramesDropped ", | ||
97 | "RxBG2FramesDropped ", | ||
98 | "RxBG3FramesDropped ", | ||
99 | "RxBG0FramesTrunc ", | ||
100 | "RxBG1FramesTrunc ", | ||
101 | "RxBG2FramesTrunc ", | ||
102 | "RxBG3FramesTrunc ", | ||
103 | |||
104 | "TSO ", | ||
105 | "TxCsumOffload ", | ||
106 | "RxCsumGood ", | ||
107 | "VLANextractions ", | ||
108 | "VLANinsertions ", | ||
109 | "GROpackets ", | ||
110 | "GROmerged ", | ||
111 | "WriteCoalSuccess ", | ||
112 | "WriteCoalFail ", | ||
113 | }; | ||
114 | |||
115 | static int get_sset_count(struct net_device *dev, int sset) | ||
116 | { | ||
117 | switch (sset) { | ||
118 | case ETH_SS_STATS: | ||
119 | return ARRAY_SIZE(stats_strings); | ||
120 | default: | ||
121 | return -EOPNOTSUPP; | ||
122 | } | ||
123 | } | ||
124 | |||
125 | static int get_regs_len(struct net_device *dev) | ||
126 | { | ||
127 | struct adapter *adap = netdev2adap(dev); | ||
128 | |||
129 | return t4_get_regs_len(adap); | ||
130 | } | ||
131 | |||
132 | static int get_eeprom_len(struct net_device *dev) | ||
133 | { | ||
134 | return EEPROMSIZE; | ||
135 | } | ||
136 | |||
137 | static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | ||
138 | { | ||
139 | struct adapter *adapter = netdev2adap(dev); | ||
140 | u32 exprom_vers; | ||
141 | |||
142 | strlcpy(info->driver, cxgb4_driver_name, sizeof(info->driver)); | ||
143 | strlcpy(info->version, cxgb4_driver_version, | ||
144 | sizeof(info->version)); | ||
145 | strlcpy(info->bus_info, pci_name(adapter->pdev), | ||
146 | sizeof(info->bus_info)); | ||
147 | |||
148 | if (adapter->params.fw_vers) | ||
149 | snprintf(info->fw_version, sizeof(info->fw_version), | ||
150 | "%u.%u.%u.%u, TP %u.%u.%u.%u", | ||
151 | FW_HDR_FW_VER_MAJOR_G(adapter->params.fw_vers), | ||
152 | FW_HDR_FW_VER_MINOR_G(adapter->params.fw_vers), | ||
153 | FW_HDR_FW_VER_MICRO_G(adapter->params.fw_vers), | ||
154 | FW_HDR_FW_VER_BUILD_G(adapter->params.fw_vers), | ||
155 | FW_HDR_FW_VER_MAJOR_G(adapter->params.tp_vers), | ||
156 | FW_HDR_FW_VER_MINOR_G(adapter->params.tp_vers), | ||
157 | FW_HDR_FW_VER_MICRO_G(adapter->params.tp_vers), | ||
158 | FW_HDR_FW_VER_BUILD_G(adapter->params.tp_vers)); | ||
159 | |||
160 | if (!t4_get_exprom_version(adapter, &exprom_vers)) | ||
161 | snprintf(info->erom_version, sizeof(info->erom_version), | ||
162 | "%u.%u.%u.%u", | ||
163 | FW_HDR_FW_VER_MAJOR_G(exprom_vers), | ||
164 | FW_HDR_FW_VER_MINOR_G(exprom_vers), | ||
165 | FW_HDR_FW_VER_MICRO_G(exprom_vers), | ||
166 | FW_HDR_FW_VER_BUILD_G(exprom_vers)); | ||
167 | } | ||
168 | |||
169 | static void get_strings(struct net_device *dev, u32 stringset, u8 *data) | ||
170 | { | ||
171 | if (stringset == ETH_SS_STATS) | ||
172 | memcpy(data, stats_strings, sizeof(stats_strings)); | ||
173 | } | ||
174 | |||
175 | /* port stats maintained per queue of the port. They should be in the same | ||
176 | * order as in stats_strings above. | ||
177 | */ | ||
178 | struct queue_port_stats { | ||
179 | u64 tso; | ||
180 | u64 tx_csum; | ||
181 | u64 rx_csum; | ||
182 | u64 vlan_ex; | ||
183 | u64 vlan_ins; | ||
184 | u64 gro_pkts; | ||
185 | u64 gro_merged; | ||
186 | }; | ||
187 | |||
188 | static void collect_sge_port_stats(const struct adapter *adap, | ||
189 | const struct port_info *p, | ||
190 | struct queue_port_stats *s) | ||
191 | { | ||
192 | int i; | ||
193 | const struct sge_eth_txq *tx = &adap->sge.ethtxq[p->first_qset]; | ||
194 | const struct sge_eth_rxq *rx = &adap->sge.ethrxq[p->first_qset]; | ||
195 | |||
196 | memset(s, 0, sizeof(*s)); | ||
197 | for (i = 0; i < p->nqsets; i++, rx++, tx++) { | ||
198 | s->tso += tx->tso; | ||
199 | s->tx_csum += tx->tx_cso; | ||
200 | s->rx_csum += rx->stats.rx_cso; | ||
201 | s->vlan_ex += rx->stats.vlan_ex; | ||
202 | s->vlan_ins += tx->vlan_ins; | ||
203 | s->gro_pkts += rx->stats.lro_pkts; | ||
204 | s->gro_merged += rx->stats.lro_merged; | ||
205 | } | ||
206 | } | ||
207 | |||
208 | static void get_stats(struct net_device *dev, struct ethtool_stats *stats, | ||
209 | u64 *data) | ||
210 | { | ||
211 | struct port_info *pi = netdev_priv(dev); | ||
212 | struct adapter *adapter = pi->adapter; | ||
213 | u32 val1, val2; | ||
214 | |||
215 | t4_get_port_stats(adapter, pi->tx_chan, (struct port_stats *)data); | ||
216 | |||
217 | data += sizeof(struct port_stats) / sizeof(u64); | ||
218 | collect_sge_port_stats(adapter, pi, (struct queue_port_stats *)data); | ||
219 | data += sizeof(struct queue_port_stats) / sizeof(u64); | ||
220 | if (!is_t4(adapter->params.chip)) { | ||
221 | t4_write_reg(adapter, SGE_STAT_CFG_A, STATSOURCE_T5_V(7)); | ||
222 | val1 = t4_read_reg(adapter, SGE_STAT_TOTAL_A); | ||
223 | val2 = t4_read_reg(adapter, SGE_STAT_MATCH_A); | ||
224 | *data = val1 - val2; | ||
225 | data++; | ||
226 | *data = val2; | ||
227 | data++; | ||
228 | } else { | ||
229 | memset(data, 0, 2 * sizeof(u64)); | ||
230 | *data += 2; | ||
231 | } | ||
232 | } | ||
233 | |||
234 | static void get_regs(struct net_device *dev, struct ethtool_regs *regs, | ||
235 | void *buf) | ||
236 | { | ||
237 | struct adapter *adap = netdev2adap(dev); | ||
238 | size_t buf_size; | ||
239 | |||
240 | buf_size = t4_get_regs_len(adap); | ||
241 | regs->version = mk_adap_vers(adap); | ||
242 | t4_get_regs(adap, buf, buf_size); | ||
243 | } | ||
244 | |||
245 | static int restart_autoneg(struct net_device *dev) | ||
246 | { | ||
247 | struct port_info *p = netdev_priv(dev); | ||
248 | |||
249 | if (!netif_running(dev)) | ||
250 | return -EAGAIN; | ||
251 | if (p->link_cfg.autoneg != AUTONEG_ENABLE) | ||
252 | return -EINVAL; | ||
253 | t4_restart_aneg(p->adapter, p->adapter->fn, p->tx_chan); | ||
254 | return 0; | ||
255 | } | ||
256 | |||
257 | static int identify_port(struct net_device *dev, | ||
258 | enum ethtool_phys_id_state state) | ||
259 | { | ||
260 | unsigned int val; | ||
261 | struct adapter *adap = netdev2adap(dev); | ||
262 | |||
263 | if (state == ETHTOOL_ID_ACTIVE) | ||
264 | val = 0xffff; | ||
265 | else if (state == ETHTOOL_ID_INACTIVE) | ||
266 | val = 0; | ||
267 | else | ||
268 | return -EINVAL; | ||
269 | |||
270 | return t4_identify_port(adap, adap->fn, netdev2pinfo(dev)->viid, val); | ||
271 | } | ||
272 | |||
273 | static unsigned int from_fw_linkcaps(enum fw_port_type type, unsigned int caps) | ||
274 | { | ||
275 | unsigned int v = 0; | ||
276 | |||
277 | if (type == FW_PORT_TYPE_BT_SGMII || type == FW_PORT_TYPE_BT_XFI || | ||
278 | type == FW_PORT_TYPE_BT_XAUI) { | ||
279 | v |= SUPPORTED_TP; | ||
280 | if (caps & FW_PORT_CAP_SPEED_100M) | ||
281 | v |= SUPPORTED_100baseT_Full; | ||
282 | if (caps & FW_PORT_CAP_SPEED_1G) | ||
283 | v |= SUPPORTED_1000baseT_Full; | ||
284 | if (caps & FW_PORT_CAP_SPEED_10G) | ||
285 | v |= SUPPORTED_10000baseT_Full; | ||
286 | } else if (type == FW_PORT_TYPE_KX4 || type == FW_PORT_TYPE_KX) { | ||
287 | v |= SUPPORTED_Backplane; | ||
288 | if (caps & FW_PORT_CAP_SPEED_1G) | ||
289 | v |= SUPPORTED_1000baseKX_Full; | ||
290 | if (caps & FW_PORT_CAP_SPEED_10G) | ||
291 | v |= SUPPORTED_10000baseKX4_Full; | ||
292 | } else if (type == FW_PORT_TYPE_KR) { | ||
293 | v |= SUPPORTED_Backplane | SUPPORTED_10000baseKR_Full; | ||
294 | } else if (type == FW_PORT_TYPE_BP_AP) { | ||
295 | v |= SUPPORTED_Backplane | SUPPORTED_10000baseR_FEC | | ||
296 | SUPPORTED_10000baseKR_Full | SUPPORTED_1000baseKX_Full; | ||
297 | } else if (type == FW_PORT_TYPE_BP4_AP) { | ||
298 | v |= SUPPORTED_Backplane | SUPPORTED_10000baseR_FEC | | ||
299 | SUPPORTED_10000baseKR_Full | SUPPORTED_1000baseKX_Full | | ||
300 | SUPPORTED_10000baseKX4_Full; | ||
301 | } else if (type == FW_PORT_TYPE_FIBER_XFI || | ||
302 | type == FW_PORT_TYPE_FIBER_XAUI || | ||
303 | type == FW_PORT_TYPE_SFP || | ||
304 | type == FW_PORT_TYPE_QSFP_10G || | ||
305 | type == FW_PORT_TYPE_QSA) { | ||
306 | v |= SUPPORTED_FIBRE; | ||
307 | if (caps & FW_PORT_CAP_SPEED_1G) | ||
308 | v |= SUPPORTED_1000baseT_Full; | ||
309 | if (caps & FW_PORT_CAP_SPEED_10G) | ||
310 | v |= SUPPORTED_10000baseT_Full; | ||
311 | } else if (type == FW_PORT_TYPE_BP40_BA || | ||
312 | type == FW_PORT_TYPE_QSFP) { | ||
313 | v |= SUPPORTED_40000baseSR4_Full; | ||
314 | v |= SUPPORTED_FIBRE; | ||
315 | } | ||
316 | |||
317 | if (caps & FW_PORT_CAP_ANEG) | ||
318 | v |= SUPPORTED_Autoneg; | ||
319 | return v; | ||
320 | } | ||
321 | |||
322 | static unsigned int to_fw_linkcaps(unsigned int caps) | ||
323 | { | ||
324 | unsigned int v = 0; | ||
325 | |||
326 | if (caps & ADVERTISED_100baseT_Full) | ||
327 | v |= FW_PORT_CAP_SPEED_100M; | ||
328 | if (caps & ADVERTISED_1000baseT_Full) | ||
329 | v |= FW_PORT_CAP_SPEED_1G; | ||
330 | if (caps & ADVERTISED_10000baseT_Full) | ||
331 | v |= FW_PORT_CAP_SPEED_10G; | ||
332 | if (caps & ADVERTISED_40000baseSR4_Full) | ||
333 | v |= FW_PORT_CAP_SPEED_40G; | ||
334 | return v; | ||
335 | } | ||
336 | |||
337 | static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
338 | { | ||
339 | const struct port_info *p = netdev_priv(dev); | ||
340 | |||
341 | if (p->port_type == FW_PORT_TYPE_BT_SGMII || | ||
342 | p->port_type == FW_PORT_TYPE_BT_XFI || | ||
343 | p->port_type == FW_PORT_TYPE_BT_XAUI) { | ||
344 | cmd->port = PORT_TP; | ||
345 | } else if (p->port_type == FW_PORT_TYPE_FIBER_XFI || | ||
346 | p->port_type == FW_PORT_TYPE_FIBER_XAUI) { | ||
347 | cmd->port = PORT_FIBRE; | ||
348 | } else if (p->port_type == FW_PORT_TYPE_SFP || | ||
349 | p->port_type == FW_PORT_TYPE_QSFP_10G || | ||
350 | p->port_type == FW_PORT_TYPE_QSA || | ||
351 | p->port_type == FW_PORT_TYPE_QSFP) { | ||
352 | if (p->mod_type == FW_PORT_MOD_TYPE_LR || | ||
353 | p->mod_type == FW_PORT_MOD_TYPE_SR || | ||
354 | p->mod_type == FW_PORT_MOD_TYPE_ER || | ||
355 | p->mod_type == FW_PORT_MOD_TYPE_LRM) | ||
356 | cmd->port = PORT_FIBRE; | ||
357 | else if (p->mod_type == FW_PORT_MOD_TYPE_TWINAX_PASSIVE || | ||
358 | p->mod_type == FW_PORT_MOD_TYPE_TWINAX_ACTIVE) | ||
359 | cmd->port = PORT_DA; | ||
360 | else | ||
361 | cmd->port = PORT_OTHER; | ||
362 | } else { | ||
363 | cmd->port = PORT_OTHER; | ||
364 | } | ||
365 | |||
366 | if (p->mdio_addr >= 0) { | ||
367 | cmd->phy_address = p->mdio_addr; | ||
368 | cmd->transceiver = XCVR_EXTERNAL; | ||
369 | cmd->mdio_support = p->port_type == FW_PORT_TYPE_BT_SGMII ? | ||
370 | MDIO_SUPPORTS_C22 : MDIO_SUPPORTS_C45; | ||
371 | } else { | ||
372 | cmd->phy_address = 0; /* not really, but no better option */ | ||
373 | cmd->transceiver = XCVR_INTERNAL; | ||
374 | cmd->mdio_support = 0; | ||
375 | } | ||
376 | |||
377 | cmd->supported = from_fw_linkcaps(p->port_type, p->link_cfg.supported); | ||
378 | cmd->advertising = from_fw_linkcaps(p->port_type, | ||
379 | p->link_cfg.advertising); | ||
380 | ethtool_cmd_speed_set(cmd, | ||
381 | netif_carrier_ok(dev) ? p->link_cfg.speed : 0); | ||
382 | cmd->duplex = DUPLEX_FULL; | ||
383 | cmd->autoneg = p->link_cfg.autoneg; | ||
384 | cmd->maxtxpkt = 0; | ||
385 | cmd->maxrxpkt = 0; | ||
386 | return 0; | ||
387 | } | ||
388 | |||
389 | static unsigned int speed_to_caps(int speed) | ||
390 | { | ||
391 | if (speed == 100) | ||
392 | return FW_PORT_CAP_SPEED_100M; | ||
393 | if (speed == 1000) | ||
394 | return FW_PORT_CAP_SPEED_1G; | ||
395 | if (speed == 10000) | ||
396 | return FW_PORT_CAP_SPEED_10G; | ||
397 | if (speed == 40000) | ||
398 | return FW_PORT_CAP_SPEED_40G; | ||
399 | return 0; | ||
400 | } | ||
401 | |||
402 | static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
403 | { | ||
404 | unsigned int cap; | ||
405 | struct port_info *p = netdev_priv(dev); | ||
406 | struct link_config *lc = &p->link_cfg; | ||
407 | u32 speed = ethtool_cmd_speed(cmd); | ||
408 | |||
409 | if (cmd->duplex != DUPLEX_FULL) /* only full-duplex supported */ | ||
410 | return -EINVAL; | ||
411 | |||
412 | if (!(lc->supported & FW_PORT_CAP_ANEG)) { | ||
413 | /* PHY offers a single speed. See if that's what's | ||
414 | * being requested. | ||
415 | */ | ||
416 | if (cmd->autoneg == AUTONEG_DISABLE && | ||
417 | (lc->supported & speed_to_caps(speed))) | ||
418 | return 0; | ||
419 | return -EINVAL; | ||
420 | } | ||
421 | |||
422 | if (cmd->autoneg == AUTONEG_DISABLE) { | ||
423 | cap = speed_to_caps(speed); | ||
424 | |||
425 | if (!(lc->supported & cap) || | ||
426 | (speed == 1000) || | ||
427 | (speed == 10000) || | ||
428 | (speed == 40000)) | ||
429 | return -EINVAL; | ||
430 | lc->requested_speed = cap; | ||
431 | lc->advertising = 0; | ||
432 | } else { | ||
433 | cap = to_fw_linkcaps(cmd->advertising); | ||
434 | if (!(lc->supported & cap)) | ||
435 | return -EINVAL; | ||
436 | lc->requested_speed = 0; | ||
437 | lc->advertising = cap | FW_PORT_CAP_ANEG; | ||
438 | } | ||
439 | lc->autoneg = cmd->autoneg; | ||
440 | |||
441 | if (netif_running(dev)) | ||
442 | return t4_link_start(p->adapter, p->adapter->fn, p->tx_chan, | ||
443 | lc); | ||
444 | return 0; | ||
445 | } | ||
446 | |||
447 | static void get_pauseparam(struct net_device *dev, | ||
448 | struct ethtool_pauseparam *epause) | ||
449 | { | ||
450 | struct port_info *p = netdev_priv(dev); | ||
451 | |||
452 | epause->autoneg = (p->link_cfg.requested_fc & PAUSE_AUTONEG) != 0; | ||
453 | epause->rx_pause = (p->link_cfg.fc & PAUSE_RX) != 0; | ||
454 | epause->tx_pause = (p->link_cfg.fc & PAUSE_TX) != 0; | ||
455 | } | ||
456 | |||
457 | static int set_pauseparam(struct net_device *dev, | ||
458 | struct ethtool_pauseparam *epause) | ||
459 | { | ||
460 | struct port_info *p = netdev_priv(dev); | ||
461 | struct link_config *lc = &p->link_cfg; | ||
462 | |||
463 | if (epause->autoneg == AUTONEG_DISABLE) | ||
464 | lc->requested_fc = 0; | ||
465 | else if (lc->supported & FW_PORT_CAP_ANEG) | ||
466 | lc->requested_fc = PAUSE_AUTONEG; | ||
467 | else | ||
468 | return -EINVAL; | ||
469 | |||
470 | if (epause->rx_pause) | ||
471 | lc->requested_fc |= PAUSE_RX; | ||
472 | if (epause->tx_pause) | ||
473 | lc->requested_fc |= PAUSE_TX; | ||
474 | if (netif_running(dev)) | ||
475 | return t4_link_start(p->adapter, p->adapter->fn, p->tx_chan, | ||
476 | lc); | ||
477 | return 0; | ||
478 | } | ||
479 | |||
480 | static void get_sge_param(struct net_device *dev, struct ethtool_ringparam *e) | ||
481 | { | ||
482 | const struct port_info *pi = netdev_priv(dev); | ||
483 | const struct sge *s = &pi->adapter->sge; | ||
484 | |||
485 | e->rx_max_pending = MAX_RX_BUFFERS; | ||
486 | e->rx_mini_max_pending = MAX_RSPQ_ENTRIES; | ||
487 | e->rx_jumbo_max_pending = 0; | ||
488 | e->tx_max_pending = MAX_TXQ_ENTRIES; | ||
489 | |||
490 | e->rx_pending = s->ethrxq[pi->first_qset].fl.size - 8; | ||
491 | e->rx_mini_pending = s->ethrxq[pi->first_qset].rspq.size; | ||
492 | e->rx_jumbo_pending = 0; | ||
493 | e->tx_pending = s->ethtxq[pi->first_qset].q.size; | ||
494 | } | ||
495 | |||
496 | static int set_sge_param(struct net_device *dev, struct ethtool_ringparam *e) | ||
497 | { | ||
498 | int i; | ||
499 | const struct port_info *pi = netdev_priv(dev); | ||
500 | struct adapter *adapter = pi->adapter; | ||
501 | struct sge *s = &adapter->sge; | ||
502 | |||
503 | if (e->rx_pending > MAX_RX_BUFFERS || e->rx_jumbo_pending || | ||
504 | e->tx_pending > MAX_TXQ_ENTRIES || | ||
505 | e->rx_mini_pending > MAX_RSPQ_ENTRIES || | ||
506 | e->rx_mini_pending < MIN_RSPQ_ENTRIES || | ||
507 | e->rx_pending < MIN_FL_ENTRIES || e->tx_pending < MIN_TXQ_ENTRIES) | ||
508 | return -EINVAL; | ||
509 | |||
510 | if (adapter->flags & FULL_INIT_DONE) | ||
511 | return -EBUSY; | ||
512 | |||
513 | for (i = 0; i < pi->nqsets; ++i) { | ||
514 | s->ethtxq[pi->first_qset + i].q.size = e->tx_pending; | ||
515 | s->ethrxq[pi->first_qset + i].fl.size = e->rx_pending + 8; | ||
516 | s->ethrxq[pi->first_qset + i].rspq.size = e->rx_mini_pending; | ||
517 | } | ||
518 | return 0; | ||
519 | } | ||
520 | |||
521 | /** | ||
522 | * set_rx_intr_params - set a net devices's RX interrupt holdoff paramete! | ||
523 | * @dev: the network device | ||
524 | * @us: the hold-off time in us, or 0 to disable timer | ||
525 | * @cnt: the hold-off packet count, or 0 to disable counter | ||
526 | * | ||
527 | * Set the RX interrupt hold-off parameters for a network device. | ||
528 | */ | ||
529 | static int set_rx_intr_params(struct net_device *dev, | ||
530 | unsigned int us, unsigned int cnt) | ||
531 | { | ||
532 | int i, err; | ||
533 | struct port_info *pi = netdev_priv(dev); | ||
534 | struct adapter *adap = pi->adapter; | ||
535 | struct sge_eth_rxq *q = &adap->sge.ethrxq[pi->first_qset]; | ||
536 | |||
537 | for (i = 0; i < pi->nqsets; i++, q++) { | ||
538 | err = cxgb4_set_rspq_intr_params(&q->rspq, us, cnt); | ||
539 | if (err) | ||
540 | return err; | ||
541 | } | ||
542 | return 0; | ||
543 | } | ||
544 | |||
545 | static int set_adaptive_rx_setting(struct net_device *dev, int adaptive_rx) | ||
546 | { | ||
547 | int i; | ||
548 | struct port_info *pi = netdev_priv(dev); | ||
549 | struct adapter *adap = pi->adapter; | ||
550 | struct sge_eth_rxq *q = &adap->sge.ethrxq[pi->first_qset]; | ||
551 | |||
552 | for (i = 0; i < pi->nqsets; i++, q++) | ||
553 | q->rspq.adaptive_rx = adaptive_rx; | ||
554 | |||
555 | return 0; | ||
556 | } | ||
557 | |||
558 | static int get_adaptive_rx_setting(struct net_device *dev) | ||
559 | { | ||
560 | struct port_info *pi = netdev_priv(dev); | ||
561 | struct adapter *adap = pi->adapter; | ||
562 | struct sge_eth_rxq *q = &adap->sge.ethrxq[pi->first_qset]; | ||
563 | |||
564 | return q->rspq.adaptive_rx; | ||
565 | } | ||
566 | |||
567 | static int set_coalesce(struct net_device *dev, struct ethtool_coalesce *c) | ||
568 | { | ||
569 | set_adaptive_rx_setting(dev, c->use_adaptive_rx_coalesce); | ||
570 | return set_rx_intr_params(dev, c->rx_coalesce_usecs, | ||
571 | c->rx_max_coalesced_frames); | ||
572 | } | ||
573 | |||
574 | static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c) | ||
575 | { | ||
576 | const struct port_info *pi = netdev_priv(dev); | ||
577 | const struct adapter *adap = pi->adapter; | ||
578 | const struct sge_rspq *rq = &adap->sge.ethrxq[pi->first_qset].rspq; | ||
579 | |||
580 | c->rx_coalesce_usecs = qtimer_val(adap, rq); | ||
581 | c->rx_max_coalesced_frames = (rq->intr_params & QINTR_CNT_EN) ? | ||
582 | adap->sge.counter_val[rq->pktcnt_idx] : 0; | ||
583 | c->use_adaptive_rx_coalesce = get_adaptive_rx_setting(dev); | ||
584 | return 0; | ||
585 | } | ||
586 | |||
587 | /** | ||
588 | * eeprom_ptov - translate a physical EEPROM address to virtual | ||
589 | * @phys_addr: the physical EEPROM address | ||
590 | * @fn: the PCI function number | ||
591 | * @sz: size of function-specific area | ||
592 | * | ||
593 | * Translate a physical EEPROM address to virtual. The first 1K is | ||
594 | * accessed through virtual addresses starting at 31K, the rest is | ||
595 | * accessed through virtual addresses starting at 0. | ||
596 | * | ||
597 | * The mapping is as follows: | ||
598 | * [0..1K) -> [31K..32K) | ||
599 | * [1K..1K+A) -> [31K-A..31K) | ||
600 | * [1K+A..ES) -> [0..ES-A-1K) | ||
601 | * | ||
602 | * where A = @fn * @sz, and ES = EEPROM size. | ||
603 | */ | ||
604 | static int eeprom_ptov(unsigned int phys_addr, unsigned int fn, unsigned int sz) | ||
605 | { | ||
606 | fn *= sz; | ||
607 | if (phys_addr < 1024) | ||
608 | return phys_addr + (31 << 10); | ||
609 | if (phys_addr < 1024 + fn) | ||
610 | return 31744 - fn + phys_addr - 1024; | ||
611 | if (phys_addr < EEPROMSIZE) | ||
612 | return phys_addr - 1024 - fn; | ||
613 | return -EINVAL; | ||
614 | } | ||
615 | |||
616 | /* The next two routines implement eeprom read/write from physical addresses. | ||
617 | */ | ||
618 | static int eeprom_rd_phys(struct adapter *adap, unsigned int phys_addr, u32 *v) | ||
619 | { | ||
620 | int vaddr = eeprom_ptov(phys_addr, adap->fn, EEPROMPFSIZE); | ||
621 | |||
622 | if (vaddr >= 0) | ||
623 | vaddr = pci_read_vpd(adap->pdev, vaddr, sizeof(u32), v); | ||
624 | return vaddr < 0 ? vaddr : 0; | ||
625 | } | ||
626 | |||
627 | static int eeprom_wr_phys(struct adapter *adap, unsigned int phys_addr, u32 v) | ||
628 | { | ||
629 | int vaddr = eeprom_ptov(phys_addr, adap->fn, EEPROMPFSIZE); | ||
630 | |||
631 | if (vaddr >= 0) | ||
632 | vaddr = pci_write_vpd(adap->pdev, vaddr, sizeof(u32), &v); | ||
633 | return vaddr < 0 ? vaddr : 0; | ||
634 | } | ||
635 | |||
636 | #define EEPROM_MAGIC 0x38E2F10C | ||
637 | |||
638 | static int get_eeprom(struct net_device *dev, struct ethtool_eeprom *e, | ||
639 | u8 *data) | ||
640 | { | ||
641 | int i, err = 0; | ||
642 | struct adapter *adapter = netdev2adap(dev); | ||
643 | u8 *buf = kmalloc(EEPROMSIZE, GFP_KERNEL); | ||
644 | |||
645 | if (!buf) | ||
646 | return -ENOMEM; | ||
647 | |||
648 | e->magic = EEPROM_MAGIC; | ||
649 | for (i = e->offset & ~3; !err && i < e->offset + e->len; i += 4) | ||
650 | err = eeprom_rd_phys(adapter, i, (u32 *)&buf[i]); | ||
651 | |||
652 | if (!err) | ||
653 | memcpy(data, buf + e->offset, e->len); | ||
654 | kfree(buf); | ||
655 | return err; | ||
656 | } | ||
657 | |||
658 | static int set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, | ||
659 | u8 *data) | ||
660 | { | ||
661 | u8 *buf; | ||
662 | int err = 0; | ||
663 | u32 aligned_offset, aligned_len, *p; | ||
664 | struct adapter *adapter = netdev2adap(dev); | ||
665 | |||
666 | if (eeprom->magic != EEPROM_MAGIC) | ||
667 | return -EINVAL; | ||
668 | |||
669 | aligned_offset = eeprom->offset & ~3; | ||
670 | aligned_len = (eeprom->len + (eeprom->offset & 3) + 3) & ~3; | ||
671 | |||
672 | if (adapter->fn > 0) { | ||
673 | u32 start = 1024 + adapter->fn * EEPROMPFSIZE; | ||
674 | |||
675 | if (aligned_offset < start || | ||
676 | aligned_offset + aligned_len > start + EEPROMPFSIZE) | ||
677 | return -EPERM; | ||
678 | } | ||
679 | |||
680 | if (aligned_offset != eeprom->offset || aligned_len != eeprom->len) { | ||
681 | /* RMW possibly needed for first or last words. | ||
682 | */ | ||
683 | buf = kmalloc(aligned_len, GFP_KERNEL); | ||
684 | if (!buf) | ||
685 | return -ENOMEM; | ||
686 | err = eeprom_rd_phys(adapter, aligned_offset, (u32 *)buf); | ||
687 | if (!err && aligned_len > 4) | ||
688 | err = eeprom_rd_phys(adapter, | ||
689 | aligned_offset + aligned_len - 4, | ||
690 | (u32 *)&buf[aligned_len - 4]); | ||
691 | if (err) | ||
692 | goto out; | ||
693 | memcpy(buf + (eeprom->offset & 3), data, eeprom->len); | ||
694 | } else { | ||
695 | buf = data; | ||
696 | } | ||
697 | |||
698 | err = t4_seeprom_wp(adapter, false); | ||
699 | if (err) | ||
700 | goto out; | ||
701 | |||
702 | for (p = (u32 *)buf; !err && aligned_len; aligned_len -= 4, p++) { | ||
703 | err = eeprom_wr_phys(adapter, aligned_offset, *p); | ||
704 | aligned_offset += 4; | ||
705 | } | ||
706 | |||
707 | if (!err) | ||
708 | err = t4_seeprom_wp(adapter, true); | ||
709 | out: | ||
710 | if (buf != data) | ||
711 | kfree(buf); | ||
712 | return err; | ||
713 | } | ||
714 | |||
715 | static int set_flash(struct net_device *netdev, struct ethtool_flash *ef) | ||
716 | { | ||
717 | int ret; | ||
718 | const struct firmware *fw; | ||
719 | struct adapter *adap = netdev2adap(netdev); | ||
720 | unsigned int mbox = PCIE_FW_MASTER_M + 1; | ||
721 | |||
722 | ef->data[sizeof(ef->data) - 1] = '\0'; | ||
723 | ret = request_firmware(&fw, ef->data, adap->pdev_dev); | ||
724 | if (ret < 0) | ||
725 | return ret; | ||
726 | |||
727 | /* If the adapter has been fully initialized then we'll go ahead and | ||
728 | * try to get the firmware's cooperation in upgrading to the new | ||
729 | * firmware image otherwise we'll try to do the entire job from the | ||
730 | * host ... and we always "force" the operation in this path. | ||
731 | */ | ||
732 | if (adap->flags & FULL_INIT_DONE) | ||
733 | mbox = adap->mbox; | ||
734 | |||
735 | ret = t4_fw_upgrade(adap, mbox, fw->data, fw->size, 1); | ||
736 | release_firmware(fw); | ||
737 | if (!ret) | ||
738 | dev_info(adap->pdev_dev, | ||
739 | "loaded firmware %s, reload cxgb4 driver\n", ef->data); | ||
740 | return ret; | ||
741 | } | ||
742 | |||
743 | #define WOL_SUPPORTED (WAKE_BCAST | WAKE_MAGIC) | ||
744 | #define BCAST_CRC 0xa0ccc1a6 | ||
745 | |||
746 | static void get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | ||
747 | { | ||
748 | wol->supported = WAKE_BCAST | WAKE_MAGIC; | ||
749 | wol->wolopts = netdev2adap(dev)->wol; | ||
750 | memset(&wol->sopass, 0, sizeof(wol->sopass)); | ||
751 | } | ||
752 | |||
753 | static int set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | ||
754 | { | ||
755 | int err = 0; | ||
756 | struct port_info *pi = netdev_priv(dev); | ||
757 | |||
758 | if (wol->wolopts & ~WOL_SUPPORTED) | ||
759 | return -EINVAL; | ||
760 | t4_wol_magic_enable(pi->adapter, pi->tx_chan, | ||
761 | (wol->wolopts & WAKE_MAGIC) ? dev->dev_addr : NULL); | ||
762 | if (wol->wolopts & WAKE_BCAST) { | ||
763 | err = t4_wol_pat_enable(pi->adapter, pi->tx_chan, 0xfe, ~0ULL, | ||
764 | ~0ULL, 0, false); | ||
765 | if (!err) | ||
766 | err = t4_wol_pat_enable(pi->adapter, pi->tx_chan, 1, | ||
767 | ~6ULL, ~0ULL, BCAST_CRC, true); | ||
768 | } else { | ||
769 | t4_wol_pat_enable(pi->adapter, pi->tx_chan, 0, 0, 0, 0, false); | ||
770 | } | ||
771 | return err; | ||
772 | } | ||
773 | |||
774 | static u32 get_rss_table_size(struct net_device *dev) | ||
775 | { | ||
776 | const struct port_info *pi = netdev_priv(dev); | ||
777 | |||
778 | return pi->rss_size; | ||
779 | } | ||
780 | |||
781 | static int get_rss_table(struct net_device *dev, u32 *p, u8 *key, u8 *hfunc) | ||
782 | { | ||
783 | const struct port_info *pi = netdev_priv(dev); | ||
784 | unsigned int n = pi->rss_size; | ||
785 | |||
786 | if (hfunc) | ||
787 | *hfunc = ETH_RSS_HASH_TOP; | ||
788 | if (!p) | ||
789 | return 0; | ||
790 | while (n--) | ||
791 | p[n] = pi->rss[n]; | ||
792 | return 0; | ||
793 | } | ||
794 | |||
795 | static int set_rss_table(struct net_device *dev, const u32 *p, const u8 *key, | ||
796 | const u8 hfunc) | ||
797 | { | ||
798 | unsigned int i; | ||
799 | struct port_info *pi = netdev_priv(dev); | ||
800 | |||
801 | /* We require at least one supported parameter to be changed and no | ||
802 | * change in any of the unsupported parameters | ||
803 | */ | ||
804 | if (key || | ||
805 | (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)) | ||
806 | return -EOPNOTSUPP; | ||
807 | if (!p) | ||
808 | return 0; | ||
809 | |||
810 | for (i = 0; i < pi->rss_size; i++) | ||
811 | pi->rss[i] = p[i]; | ||
812 | if (pi->adapter->flags & FULL_INIT_DONE) | ||
813 | return cxgb4_write_rss(pi, pi->rss); | ||
814 | return 0; | ||
815 | } | ||
816 | |||
817 | static int get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info, | ||
818 | u32 *rules) | ||
819 | { | ||
820 | const struct port_info *pi = netdev_priv(dev); | ||
821 | |||
822 | switch (info->cmd) { | ||
823 | case ETHTOOL_GRXFH: { | ||
824 | unsigned int v = pi->rss_mode; | ||
825 | |||
826 | info->data = 0; | ||
827 | switch (info->flow_type) { | ||
828 | case TCP_V4_FLOW: | ||
829 | if (v & FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN_F) | ||
830 | info->data = RXH_IP_SRC | RXH_IP_DST | | ||
831 | RXH_L4_B_0_1 | RXH_L4_B_2_3; | ||
832 | else if (v & FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN_F) | ||
833 | info->data = RXH_IP_SRC | RXH_IP_DST; | ||
834 | break; | ||
835 | case UDP_V4_FLOW: | ||
836 | if ((v & FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN_F) && | ||
837 | (v & FW_RSS_VI_CONFIG_CMD_UDPEN_F)) | ||
838 | info->data = RXH_IP_SRC | RXH_IP_DST | | ||
839 | RXH_L4_B_0_1 | RXH_L4_B_2_3; | ||
840 | else if (v & FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN_F) | ||
841 | info->data = RXH_IP_SRC | RXH_IP_DST; | ||
842 | break; | ||
843 | case SCTP_V4_FLOW: | ||
844 | case AH_ESP_V4_FLOW: | ||
845 | case IPV4_FLOW: | ||
846 | if (v & FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN_F) | ||
847 | info->data = RXH_IP_SRC | RXH_IP_DST; | ||
848 | break; | ||
849 | case TCP_V6_FLOW: | ||
850 | if (v & FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN_F) | ||
851 | info->data = RXH_IP_SRC | RXH_IP_DST | | ||
852 | RXH_L4_B_0_1 | RXH_L4_B_2_3; | ||
853 | else if (v & FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN_F) | ||
854 | info->data = RXH_IP_SRC | RXH_IP_DST; | ||
855 | break; | ||
856 | case UDP_V6_FLOW: | ||
857 | if ((v & FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN_F) && | ||
858 | (v & FW_RSS_VI_CONFIG_CMD_UDPEN_F)) | ||
859 | info->data = RXH_IP_SRC | RXH_IP_DST | | ||
860 | RXH_L4_B_0_1 | RXH_L4_B_2_3; | ||
861 | else if (v & FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN_F) | ||
862 | info->data = RXH_IP_SRC | RXH_IP_DST; | ||
863 | break; | ||
864 | case SCTP_V6_FLOW: | ||
865 | case AH_ESP_V6_FLOW: | ||
866 | case IPV6_FLOW: | ||
867 | if (v & FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN_F) | ||
868 | info->data = RXH_IP_SRC | RXH_IP_DST; | ||
869 | break; | ||
870 | } | ||
871 | return 0; | ||
872 | } | ||
873 | case ETHTOOL_GRXRINGS: | ||
874 | info->data = pi->nqsets; | ||
875 | return 0; | ||
876 | } | ||
877 | return -EOPNOTSUPP; | ||
878 | } | ||
879 | |||
880 | static const struct ethtool_ops cxgb_ethtool_ops = { | ||
881 | .get_settings = get_settings, | ||
882 | .set_settings = set_settings, | ||
883 | .get_drvinfo = get_drvinfo, | ||
884 | .get_msglevel = get_msglevel, | ||
885 | .set_msglevel = set_msglevel, | ||
886 | .get_ringparam = get_sge_param, | ||
887 | .set_ringparam = set_sge_param, | ||
888 | .get_coalesce = get_coalesce, | ||
889 | .set_coalesce = set_coalesce, | ||
890 | .get_eeprom_len = get_eeprom_len, | ||
891 | .get_eeprom = get_eeprom, | ||
892 | .set_eeprom = set_eeprom, | ||
893 | .get_pauseparam = get_pauseparam, | ||
894 | .set_pauseparam = set_pauseparam, | ||
895 | .get_link = ethtool_op_get_link, | ||
896 | .get_strings = get_strings, | ||
897 | .set_phys_id = identify_port, | ||
898 | .nway_reset = restart_autoneg, | ||
899 | .get_sset_count = get_sset_count, | ||
900 | .get_ethtool_stats = get_stats, | ||
901 | .get_regs_len = get_regs_len, | ||
902 | .get_regs = get_regs, | ||
903 | .get_wol = get_wol, | ||
904 | .set_wol = set_wol, | ||
905 | .get_rxnfc = get_rxnfc, | ||
906 | .get_rxfh_indir_size = get_rss_table_size, | ||
907 | .get_rxfh = get_rss_table, | ||
908 | .set_rxfh = set_rss_table, | ||
909 | .flash_device = set_flash, | ||
910 | }; | ||
911 | |||
912 | void cxgb4_set_ethtool_ops(struct net_device *netdev) | ||
913 | { | ||
914 | netdev->ethtool_ops = &cxgb_ethtool_ops; | ||
915 | } | ||
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 58c537f16763..24e10ea3d5ef 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | |||
@@ -76,23 +76,15 @@ | |||
76 | #include "clip_tbl.h" | 76 | #include "clip_tbl.h" |
77 | #include "l2t.h" | 77 | #include "l2t.h" |
78 | 78 | ||
79 | char cxgb4_driver_name[] = KBUILD_MODNAME; | ||
80 | |||
79 | #ifdef DRV_VERSION | 81 | #ifdef DRV_VERSION |
80 | #undef DRV_VERSION | 82 | #undef DRV_VERSION |
81 | #endif | 83 | #endif |
82 | #define DRV_VERSION "2.0.0-ko" | 84 | #define DRV_VERSION "2.0.0-ko" |
85 | const char cxgb4_driver_version[] = DRV_VERSION; | ||
83 | #define DRV_DESC "Chelsio T4/T5 Network Driver" | 86 | #define DRV_DESC "Chelsio T4/T5 Network Driver" |
84 | 87 | ||
85 | enum { | ||
86 | MAX_TXQ_ENTRIES = 16384, | ||
87 | MAX_CTRL_TXQ_ENTRIES = 1024, | ||
88 | MAX_RSPQ_ENTRIES = 16384, | ||
89 | MAX_RX_BUFFERS = 16384, | ||
90 | MIN_TXQ_ENTRIES = 32, | ||
91 | MIN_CTRL_TXQ_ENTRIES = 32, | ||
92 | MIN_RSPQ_ENTRIES = 128, | ||
93 | MIN_FL_ENTRIES = 16 | ||
94 | }; | ||
95 | |||
96 | /* Host shadow copy of ingress filter entry. This is in host native format | 88 | /* Host shadow copy of ingress filter entry. This is in host native format |
97 | * and doesn't match the ordering or bit order, etc. of the hardware of the | 89 | * and doesn't match the ordering or bit order, etc. of the hardware of the |
98 | * firmware command. The use of bit-field structure elements is purely to | 90 | * firmware command. The use of bit-field structure elements is purely to |
@@ -857,14 +849,14 @@ static void free_msix_queue_irqs(struct adapter *adap) | |||
857 | } | 849 | } |
858 | 850 | ||
859 | /** | 851 | /** |
860 | * write_rss - write the RSS table for a given port | 852 | * cxgb4_write_rss - write the RSS table for a given port |
861 | * @pi: the port | 853 | * @pi: the port |
862 | * @queues: array of queue indices for RSS | 854 | * @queues: array of queue indices for RSS |
863 | * | 855 | * |
864 | * Sets up the portion of the HW RSS table for the port's VI to distribute | 856 | * Sets up the portion of the HW RSS table for the port's VI to distribute |
865 | * packets to the Rx queues in @queues. | 857 | * packets to the Rx queues in @queues. |
866 | */ | 858 | */ |
867 | static int write_rss(const struct port_info *pi, const u16 *queues) | 859 | int cxgb4_write_rss(const struct port_info *pi, const u16 *queues) |
868 | { | 860 | { |
869 | u16 *rss; | 861 | u16 *rss; |
870 | int i, err; | 862 | int i, err; |
@@ -897,7 +889,7 @@ static int setup_rss(struct adapter *adap) | |||
897 | for_each_port(adap, i) { | 889 | for_each_port(adap, i) { |
898 | const struct port_info *pi = adap2pinfo(adap, i); | 890 | const struct port_info *pi = adap2pinfo(adap, i); |
899 | 891 | ||
900 | err = write_rss(pi, pi->rss); | 892 | err = cxgb4_write_rss(pi, pi->rss); |
901 | if (err) | 893 | if (err) |
902 | return err; | 894 | return err; |
903 | } | 895 | } |
@@ -1327,1192 +1319,6 @@ static inline int is_offload(const struct adapter *adap) | |||
1327 | return adap->params.offload; | 1319 | return adap->params.offload; |
1328 | } | 1320 | } |
1329 | 1321 | ||
1330 | /* | ||
1331 | * Implementation of ethtool operations. | ||
1332 | */ | ||
1333 | |||
1334 | static u32 get_msglevel(struct net_device *dev) | ||
1335 | { | ||
1336 | return netdev2adap(dev)->msg_enable; | ||
1337 | } | ||
1338 | |||
1339 | static void set_msglevel(struct net_device *dev, u32 val) | ||
1340 | { | ||
1341 | netdev2adap(dev)->msg_enable = val; | ||
1342 | } | ||
1343 | |||
1344 | static char stats_strings[][ETH_GSTRING_LEN] = { | ||
1345 | "TxOctetsOK ", | ||
1346 | "TxFramesOK ", | ||
1347 | "TxBroadcastFrames ", | ||
1348 | "TxMulticastFrames ", | ||
1349 | "TxUnicastFrames ", | ||
1350 | "TxErrorFrames ", | ||
1351 | |||
1352 | "TxFrames64 ", | ||
1353 | "TxFrames65To127 ", | ||
1354 | "TxFrames128To255 ", | ||
1355 | "TxFrames256To511 ", | ||
1356 | "TxFrames512To1023 ", | ||
1357 | "TxFrames1024To1518 ", | ||
1358 | "TxFrames1519ToMax ", | ||
1359 | |||
1360 | "TxFramesDropped ", | ||
1361 | "TxPauseFrames ", | ||
1362 | "TxPPP0Frames ", | ||
1363 | "TxPPP1Frames ", | ||
1364 | "TxPPP2Frames ", | ||
1365 | "TxPPP3Frames ", | ||
1366 | "TxPPP4Frames ", | ||
1367 | "TxPPP5Frames ", | ||
1368 | "TxPPP6Frames ", | ||
1369 | "TxPPP7Frames ", | ||
1370 | |||
1371 | "RxOctetsOK ", | ||
1372 | "RxFramesOK ", | ||
1373 | "RxBroadcastFrames ", | ||
1374 | "RxMulticastFrames ", | ||
1375 | "RxUnicastFrames ", | ||
1376 | |||
1377 | "RxFramesTooLong ", | ||
1378 | "RxJabberErrors ", | ||
1379 | "RxFCSErrors ", | ||
1380 | "RxLengthErrors ", | ||
1381 | "RxSymbolErrors ", | ||
1382 | "RxRuntFrames ", | ||
1383 | |||
1384 | "RxFrames64 ", | ||
1385 | "RxFrames65To127 ", | ||
1386 | "RxFrames128To255 ", | ||
1387 | "RxFrames256To511 ", | ||
1388 | "RxFrames512To1023 ", | ||
1389 | "RxFrames1024To1518 ", | ||
1390 | "RxFrames1519ToMax ", | ||
1391 | |||
1392 | "RxPauseFrames ", | ||
1393 | "RxPPP0Frames ", | ||
1394 | "RxPPP1Frames ", | ||
1395 | "RxPPP2Frames ", | ||
1396 | "RxPPP3Frames ", | ||
1397 | "RxPPP4Frames ", | ||
1398 | "RxPPP5Frames ", | ||
1399 | "RxPPP6Frames ", | ||
1400 | "RxPPP7Frames ", | ||
1401 | |||
1402 | "RxBG0FramesDropped ", | ||
1403 | "RxBG1FramesDropped ", | ||
1404 | "RxBG2FramesDropped ", | ||
1405 | "RxBG3FramesDropped ", | ||
1406 | "RxBG0FramesTrunc ", | ||
1407 | "RxBG1FramesTrunc ", | ||
1408 | "RxBG2FramesTrunc ", | ||
1409 | "RxBG3FramesTrunc ", | ||
1410 | |||
1411 | "TSO ", | ||
1412 | "TxCsumOffload ", | ||
1413 | "RxCsumGood ", | ||
1414 | "VLANextractions ", | ||
1415 | "VLANinsertions ", | ||
1416 | "GROpackets ", | ||
1417 | "GROmerged ", | ||
1418 | "WriteCoalSuccess ", | ||
1419 | "WriteCoalFail ", | ||
1420 | }; | ||
1421 | |||
1422 | static int get_sset_count(struct net_device *dev, int sset) | ||
1423 | { | ||
1424 | switch (sset) { | ||
1425 | case ETH_SS_STATS: | ||
1426 | return ARRAY_SIZE(stats_strings); | ||
1427 | default: | ||
1428 | return -EOPNOTSUPP; | ||
1429 | } | ||
1430 | } | ||
1431 | |||
1432 | #define T4_REGMAP_SIZE (160 * 1024) | ||
1433 | #define T5_REGMAP_SIZE (332 * 1024) | ||
1434 | |||
1435 | static int get_regs_len(struct net_device *dev) | ||
1436 | { | ||
1437 | struct adapter *adap = netdev2adap(dev); | ||
1438 | if (is_t4(adap->params.chip)) | ||
1439 | return T4_REGMAP_SIZE; | ||
1440 | else | ||
1441 | return T5_REGMAP_SIZE; | ||
1442 | } | ||
1443 | |||
1444 | static int get_eeprom_len(struct net_device *dev) | ||
1445 | { | ||
1446 | return EEPROMSIZE; | ||
1447 | } | ||
1448 | |||
1449 | static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | ||
1450 | { | ||
1451 | struct adapter *adapter = netdev2adap(dev); | ||
1452 | u32 exprom_vers; | ||
1453 | |||
1454 | strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); | ||
1455 | strlcpy(info->version, DRV_VERSION, sizeof(info->version)); | ||
1456 | strlcpy(info->bus_info, pci_name(adapter->pdev), | ||
1457 | sizeof(info->bus_info)); | ||
1458 | |||
1459 | if (adapter->params.fw_vers) | ||
1460 | snprintf(info->fw_version, sizeof(info->fw_version), | ||
1461 | "%u.%u.%u.%u, TP %u.%u.%u.%u", | ||
1462 | FW_HDR_FW_VER_MAJOR_G(adapter->params.fw_vers), | ||
1463 | FW_HDR_FW_VER_MINOR_G(adapter->params.fw_vers), | ||
1464 | FW_HDR_FW_VER_MICRO_G(adapter->params.fw_vers), | ||
1465 | FW_HDR_FW_VER_BUILD_G(adapter->params.fw_vers), | ||
1466 | FW_HDR_FW_VER_MAJOR_G(adapter->params.tp_vers), | ||
1467 | FW_HDR_FW_VER_MINOR_G(adapter->params.tp_vers), | ||
1468 | FW_HDR_FW_VER_MICRO_G(adapter->params.tp_vers), | ||
1469 | FW_HDR_FW_VER_BUILD_G(adapter->params.tp_vers)); | ||
1470 | |||
1471 | if (!t4_get_exprom_version(adapter, &exprom_vers)) | ||
1472 | snprintf(info->erom_version, sizeof(info->erom_version), | ||
1473 | "%u.%u.%u.%u", | ||
1474 | FW_HDR_FW_VER_MAJOR_G(exprom_vers), | ||
1475 | FW_HDR_FW_VER_MINOR_G(exprom_vers), | ||
1476 | FW_HDR_FW_VER_MICRO_G(exprom_vers), | ||
1477 | FW_HDR_FW_VER_BUILD_G(exprom_vers)); | ||
1478 | } | ||
1479 | |||
1480 | static void get_strings(struct net_device *dev, u32 stringset, u8 *data) | ||
1481 | { | ||
1482 | if (stringset == ETH_SS_STATS) | ||
1483 | memcpy(data, stats_strings, sizeof(stats_strings)); | ||
1484 | } | ||
1485 | |||
1486 | /* | ||
1487 | * port stats maintained per queue of the port. They should be in the same | ||
1488 | * order as in stats_strings above. | ||
1489 | */ | ||
1490 | struct queue_port_stats { | ||
1491 | u64 tso; | ||
1492 | u64 tx_csum; | ||
1493 | u64 rx_csum; | ||
1494 | u64 vlan_ex; | ||
1495 | u64 vlan_ins; | ||
1496 | u64 gro_pkts; | ||
1497 | u64 gro_merged; | ||
1498 | }; | ||
1499 | |||
1500 | static void collect_sge_port_stats(const struct adapter *adap, | ||
1501 | const struct port_info *p, struct queue_port_stats *s) | ||
1502 | { | ||
1503 | int i; | ||
1504 | const struct sge_eth_txq *tx = &adap->sge.ethtxq[p->first_qset]; | ||
1505 | const struct sge_eth_rxq *rx = &adap->sge.ethrxq[p->first_qset]; | ||
1506 | |||
1507 | memset(s, 0, sizeof(*s)); | ||
1508 | for (i = 0; i < p->nqsets; i++, rx++, tx++) { | ||
1509 | s->tso += tx->tso; | ||
1510 | s->tx_csum += tx->tx_cso; | ||
1511 | s->rx_csum += rx->stats.rx_cso; | ||
1512 | s->vlan_ex += rx->stats.vlan_ex; | ||
1513 | s->vlan_ins += tx->vlan_ins; | ||
1514 | s->gro_pkts += rx->stats.lro_pkts; | ||
1515 | s->gro_merged += rx->stats.lro_merged; | ||
1516 | } | ||
1517 | } | ||
1518 | |||
1519 | static void get_stats(struct net_device *dev, struct ethtool_stats *stats, | ||
1520 | u64 *data) | ||
1521 | { | ||
1522 | struct port_info *pi = netdev_priv(dev); | ||
1523 | struct adapter *adapter = pi->adapter; | ||
1524 | u32 val1, val2; | ||
1525 | |||
1526 | t4_get_port_stats(adapter, pi->tx_chan, (struct port_stats *)data); | ||
1527 | |||
1528 | data += sizeof(struct port_stats) / sizeof(u64); | ||
1529 | collect_sge_port_stats(adapter, pi, (struct queue_port_stats *)data); | ||
1530 | data += sizeof(struct queue_port_stats) / sizeof(u64); | ||
1531 | if (!is_t4(adapter->params.chip)) { | ||
1532 | t4_write_reg(adapter, SGE_STAT_CFG_A, STATSOURCE_T5_V(7)); | ||
1533 | val1 = t4_read_reg(adapter, SGE_STAT_TOTAL_A); | ||
1534 | val2 = t4_read_reg(adapter, SGE_STAT_MATCH_A); | ||
1535 | *data = val1 - val2; | ||
1536 | data++; | ||
1537 | *data = val2; | ||
1538 | data++; | ||
1539 | } else { | ||
1540 | memset(data, 0, 2 * sizeof(u64)); | ||
1541 | *data += 2; | ||
1542 | } | ||
1543 | } | ||
1544 | |||
1545 | /* | ||
1546 | * Return a version number to identify the type of adapter. The scheme is: | ||
1547 | * - bits 0..9: chip version | ||
1548 | * - bits 10..15: chip revision | ||
1549 | * - bits 16..23: register dump version | ||
1550 | */ | ||
1551 | static inline unsigned int mk_adap_vers(const struct adapter *ap) | ||
1552 | { | ||
1553 | return CHELSIO_CHIP_VERSION(ap->params.chip) | | ||
1554 | (CHELSIO_CHIP_RELEASE(ap->params.chip) << 10) | (1 << 16); | ||
1555 | } | ||
1556 | |||
1557 | static void reg_block_dump(struct adapter *ap, void *buf, unsigned int start, | ||
1558 | unsigned int end) | ||
1559 | { | ||
1560 | u32 *p = buf + start; | ||
1561 | |||
1562 | for ( ; start <= end; start += sizeof(u32)) | ||
1563 | *p++ = t4_read_reg(ap, start); | ||
1564 | } | ||
1565 | |||
1566 | static void get_regs(struct net_device *dev, struct ethtool_regs *regs, | ||
1567 | void *buf) | ||
1568 | { | ||
1569 | static const unsigned int t4_reg_ranges[] = { | ||
1570 | 0x1008, 0x1108, | ||
1571 | 0x1180, 0x11b4, | ||
1572 | 0x11fc, 0x123c, | ||
1573 | 0x1300, 0x173c, | ||
1574 | 0x1800, 0x18fc, | ||
1575 | 0x3000, 0x30d8, | ||
1576 | 0x30e0, 0x5924, | ||
1577 | 0x5960, 0x59d4, | ||
1578 | 0x5a00, 0x5af8, | ||
1579 | 0x6000, 0x6098, | ||
1580 | 0x6100, 0x6150, | ||
1581 | 0x6200, 0x6208, | ||
1582 | 0x6240, 0x6248, | ||
1583 | 0x6280, 0x6338, | ||
1584 | 0x6370, 0x638c, | ||
1585 | 0x6400, 0x643c, | ||
1586 | 0x6500, 0x6524, | ||
1587 | 0x6a00, 0x6a38, | ||
1588 | 0x6a60, 0x6a78, | ||
1589 | 0x6b00, 0x6b84, | ||
1590 | 0x6bf0, 0x6c84, | ||
1591 | 0x6cf0, 0x6d84, | ||
1592 | 0x6df0, 0x6e84, | ||
1593 | 0x6ef0, 0x6f84, | ||
1594 | 0x6ff0, 0x7084, | ||
1595 | 0x70f0, 0x7184, | ||
1596 | 0x71f0, 0x7284, | ||
1597 | 0x72f0, 0x7384, | ||
1598 | 0x73f0, 0x7450, | ||
1599 | 0x7500, 0x7530, | ||
1600 | 0x7600, 0x761c, | ||
1601 | 0x7680, 0x76cc, | ||
1602 | 0x7700, 0x7798, | ||
1603 | 0x77c0, 0x77fc, | ||
1604 | 0x7900, 0x79fc, | ||
1605 | 0x7b00, 0x7c38, | ||
1606 | 0x7d00, 0x7efc, | ||
1607 | 0x8dc0, 0x8e1c, | ||
1608 | 0x8e30, 0x8e78, | ||
1609 | 0x8ea0, 0x8f6c, | ||
1610 | 0x8fc0, 0x9074, | ||
1611 | 0x90fc, 0x90fc, | ||
1612 | 0x9400, 0x9458, | ||
1613 | 0x9600, 0x96bc, | ||
1614 | 0x9800, 0x9808, | ||
1615 | 0x9820, 0x983c, | ||
1616 | 0x9850, 0x9864, | ||
1617 | 0x9c00, 0x9c6c, | ||
1618 | 0x9c80, 0x9cec, | ||
1619 | 0x9d00, 0x9d6c, | ||
1620 | 0x9d80, 0x9dec, | ||
1621 | 0x9e00, 0x9e6c, | ||
1622 | 0x9e80, 0x9eec, | ||
1623 | 0x9f00, 0x9f6c, | ||
1624 | 0x9f80, 0x9fec, | ||
1625 | 0xd004, 0xd03c, | ||
1626 | 0xdfc0, 0xdfe0, | ||
1627 | 0xe000, 0xea7c, | ||
1628 | 0xf000, 0x11110, | ||
1629 | 0x11118, 0x11190, | ||
1630 | 0x19040, 0x1906c, | ||
1631 | 0x19078, 0x19080, | ||
1632 | 0x1908c, 0x19124, | ||
1633 | 0x19150, 0x191b0, | ||
1634 | 0x191d0, 0x191e8, | ||
1635 | 0x19238, 0x1924c, | ||
1636 | 0x193f8, 0x19474, | ||
1637 | 0x19490, 0x194f8, | ||
1638 | 0x19800, 0x19f30, | ||
1639 | 0x1a000, 0x1a06c, | ||
1640 | 0x1a0b0, 0x1a120, | ||
1641 | 0x1a128, 0x1a138, | ||
1642 | 0x1a190, 0x1a1c4, | ||
1643 | 0x1a1fc, 0x1a1fc, | ||
1644 | 0x1e040, 0x1e04c, | ||
1645 | 0x1e284, 0x1e28c, | ||
1646 | 0x1e2c0, 0x1e2c0, | ||
1647 | 0x1e2e0, 0x1e2e0, | ||
1648 | 0x1e300, 0x1e384, | ||
1649 | 0x1e3c0, 0x1e3c8, | ||
1650 | 0x1e440, 0x1e44c, | ||
1651 | 0x1e684, 0x1e68c, | ||
1652 | 0x1e6c0, 0x1e6c0, | ||
1653 | 0x1e6e0, 0x1e6e0, | ||
1654 | 0x1e700, 0x1e784, | ||
1655 | 0x1e7c0, 0x1e7c8, | ||
1656 | 0x1e840, 0x1e84c, | ||
1657 | 0x1ea84, 0x1ea8c, | ||
1658 | 0x1eac0, 0x1eac0, | ||
1659 | 0x1eae0, 0x1eae0, | ||
1660 | 0x1eb00, 0x1eb84, | ||
1661 | 0x1ebc0, 0x1ebc8, | ||
1662 | 0x1ec40, 0x1ec4c, | ||
1663 | 0x1ee84, 0x1ee8c, | ||
1664 | 0x1eec0, 0x1eec0, | ||
1665 | 0x1eee0, 0x1eee0, | ||
1666 | 0x1ef00, 0x1ef84, | ||
1667 | 0x1efc0, 0x1efc8, | ||
1668 | 0x1f040, 0x1f04c, | ||
1669 | 0x1f284, 0x1f28c, | ||
1670 | 0x1f2c0, 0x1f2c0, | ||
1671 | 0x1f2e0, 0x1f2e0, | ||
1672 | 0x1f300, 0x1f384, | ||
1673 | 0x1f3c0, 0x1f3c8, | ||
1674 | 0x1f440, 0x1f44c, | ||
1675 | 0x1f684, 0x1f68c, | ||
1676 | 0x1f6c0, 0x1f6c0, | ||
1677 | 0x1f6e0, 0x1f6e0, | ||
1678 | 0x1f700, 0x1f784, | ||
1679 | 0x1f7c0, 0x1f7c8, | ||
1680 | 0x1f840, 0x1f84c, | ||
1681 | 0x1fa84, 0x1fa8c, | ||
1682 | 0x1fac0, 0x1fac0, | ||
1683 | 0x1fae0, 0x1fae0, | ||
1684 | 0x1fb00, 0x1fb84, | ||
1685 | 0x1fbc0, 0x1fbc8, | ||
1686 | 0x1fc40, 0x1fc4c, | ||
1687 | 0x1fe84, 0x1fe8c, | ||
1688 | 0x1fec0, 0x1fec0, | ||
1689 | 0x1fee0, 0x1fee0, | ||
1690 | 0x1ff00, 0x1ff84, | ||
1691 | 0x1ffc0, 0x1ffc8, | ||
1692 | 0x20000, 0x2002c, | ||
1693 | 0x20100, 0x2013c, | ||
1694 | 0x20190, 0x201c8, | ||
1695 | 0x20200, 0x20318, | ||
1696 | 0x20400, 0x20528, | ||
1697 | 0x20540, 0x20614, | ||
1698 | 0x21000, 0x21040, | ||
1699 | 0x2104c, 0x21060, | ||
1700 | 0x210c0, 0x210ec, | ||
1701 | 0x21200, 0x21268, | ||
1702 | 0x21270, 0x21284, | ||
1703 | 0x212fc, 0x21388, | ||
1704 | 0x21400, 0x21404, | ||
1705 | 0x21500, 0x21518, | ||
1706 | 0x2152c, 0x2153c, | ||
1707 | 0x21550, 0x21554, | ||
1708 | 0x21600, 0x21600, | ||
1709 | 0x21608, 0x21628, | ||
1710 | 0x21630, 0x2163c, | ||
1711 | 0x21700, 0x2171c, | ||
1712 | 0x21780, 0x2178c, | ||
1713 | 0x21800, 0x21c38, | ||
1714 | 0x21c80, 0x21d7c, | ||
1715 | 0x21e00, 0x21e04, | ||
1716 | 0x22000, 0x2202c, | ||
1717 | 0x22100, 0x2213c, | ||
1718 | 0x22190, 0x221c8, | ||
1719 | 0x22200, 0x22318, | ||
1720 | 0x22400, 0x22528, | ||
1721 | 0x22540, 0x22614, | ||
1722 | 0x23000, 0x23040, | ||
1723 | 0x2304c, 0x23060, | ||
1724 | 0x230c0, 0x230ec, | ||
1725 | 0x23200, 0x23268, | ||
1726 | 0x23270, 0x23284, | ||
1727 | 0x232fc, 0x23388, | ||
1728 | 0x23400, 0x23404, | ||
1729 | 0x23500, 0x23518, | ||
1730 | 0x2352c, 0x2353c, | ||
1731 | 0x23550, 0x23554, | ||
1732 | 0x23600, 0x23600, | ||
1733 | 0x23608, 0x23628, | ||
1734 | 0x23630, 0x2363c, | ||
1735 | 0x23700, 0x2371c, | ||
1736 | 0x23780, 0x2378c, | ||
1737 | 0x23800, 0x23c38, | ||
1738 | 0x23c80, 0x23d7c, | ||
1739 | 0x23e00, 0x23e04, | ||
1740 | 0x24000, 0x2402c, | ||
1741 | 0x24100, 0x2413c, | ||
1742 | 0x24190, 0x241c8, | ||
1743 | 0x24200, 0x24318, | ||
1744 | 0x24400, 0x24528, | ||
1745 | 0x24540, 0x24614, | ||
1746 | 0x25000, 0x25040, | ||
1747 | 0x2504c, 0x25060, | ||
1748 | 0x250c0, 0x250ec, | ||
1749 | 0x25200, 0x25268, | ||
1750 | 0x25270, 0x25284, | ||
1751 | 0x252fc, 0x25388, | ||
1752 | 0x25400, 0x25404, | ||
1753 | 0x25500, 0x25518, | ||
1754 | 0x2552c, 0x2553c, | ||
1755 | 0x25550, 0x25554, | ||
1756 | 0x25600, 0x25600, | ||
1757 | 0x25608, 0x25628, | ||
1758 | 0x25630, 0x2563c, | ||
1759 | 0x25700, 0x2571c, | ||
1760 | 0x25780, 0x2578c, | ||
1761 | 0x25800, 0x25c38, | ||
1762 | 0x25c80, 0x25d7c, | ||
1763 | 0x25e00, 0x25e04, | ||
1764 | 0x26000, 0x2602c, | ||
1765 | 0x26100, 0x2613c, | ||
1766 | 0x26190, 0x261c8, | ||
1767 | 0x26200, 0x26318, | ||
1768 | 0x26400, 0x26528, | ||
1769 | 0x26540, 0x26614, | ||
1770 | 0x27000, 0x27040, | ||
1771 | 0x2704c, 0x27060, | ||
1772 | 0x270c0, 0x270ec, | ||
1773 | 0x27200, 0x27268, | ||
1774 | 0x27270, 0x27284, | ||
1775 | 0x272fc, 0x27388, | ||
1776 | 0x27400, 0x27404, | ||
1777 | 0x27500, 0x27518, | ||
1778 | 0x2752c, 0x2753c, | ||
1779 | 0x27550, 0x27554, | ||
1780 | 0x27600, 0x27600, | ||
1781 | 0x27608, 0x27628, | ||
1782 | 0x27630, 0x2763c, | ||
1783 | 0x27700, 0x2771c, | ||
1784 | 0x27780, 0x2778c, | ||
1785 | 0x27800, 0x27c38, | ||
1786 | 0x27c80, 0x27d7c, | ||
1787 | 0x27e00, 0x27e04 | ||
1788 | }; | ||
1789 | |||
1790 | static const unsigned int t5_reg_ranges[] = { | ||
1791 | 0x1008, 0x1148, | ||
1792 | 0x1180, 0x11b4, | ||
1793 | 0x11fc, 0x123c, | ||
1794 | 0x1280, 0x173c, | ||
1795 | 0x1800, 0x18fc, | ||
1796 | 0x3000, 0x3028, | ||
1797 | 0x3060, 0x30d8, | ||
1798 | 0x30e0, 0x30fc, | ||
1799 | 0x3140, 0x357c, | ||
1800 | 0x35a8, 0x35cc, | ||
1801 | 0x35ec, 0x35ec, | ||
1802 | 0x3600, 0x5624, | ||
1803 | 0x56cc, 0x575c, | ||
1804 | 0x580c, 0x5814, | ||
1805 | 0x5890, 0x58bc, | ||
1806 | 0x5940, 0x59dc, | ||
1807 | 0x59fc, 0x5a18, | ||
1808 | 0x5a60, 0x5a9c, | ||
1809 | 0x5b9c, 0x5bfc, | ||
1810 | 0x6000, 0x6040, | ||
1811 | 0x6058, 0x614c, | ||
1812 | 0x7700, 0x7798, | ||
1813 | 0x77c0, 0x78fc, | ||
1814 | 0x7b00, 0x7c54, | ||
1815 | 0x7d00, 0x7efc, | ||
1816 | 0x8dc0, 0x8de0, | ||
1817 | 0x8df8, 0x8e84, | ||
1818 | 0x8ea0, 0x8f84, | ||
1819 | 0x8fc0, 0x90f8, | ||
1820 | 0x9400, 0x9470, | ||
1821 | 0x9600, 0x96f4, | ||
1822 | 0x9800, 0x9808, | ||
1823 | 0x9820, 0x983c, | ||
1824 | 0x9850, 0x9864, | ||
1825 | 0x9c00, 0x9c6c, | ||
1826 | 0x9c80, 0x9cec, | ||
1827 | 0x9d00, 0x9d6c, | ||
1828 | 0x9d80, 0x9dec, | ||
1829 | 0x9e00, 0x9e6c, | ||
1830 | 0x9e80, 0x9eec, | ||
1831 | 0x9f00, 0x9f6c, | ||
1832 | 0x9f80, 0xa020, | ||
1833 | 0xd004, 0xd03c, | ||
1834 | 0xdfc0, 0xdfe0, | ||
1835 | 0xe000, 0x11088, | ||
1836 | 0x1109c, 0x11110, | ||
1837 | 0x11118, 0x1117c, | ||
1838 | 0x11190, 0x11204, | ||
1839 | 0x19040, 0x1906c, | ||
1840 | 0x19078, 0x19080, | ||
1841 | 0x1908c, 0x19124, | ||
1842 | 0x19150, 0x191b0, | ||
1843 | 0x191d0, 0x191e8, | ||
1844 | 0x19238, 0x19290, | ||
1845 | 0x193f8, 0x19474, | ||
1846 | 0x19490, 0x194cc, | ||
1847 | 0x194f0, 0x194f8, | ||
1848 | 0x19c00, 0x19c60, | ||
1849 | 0x19c94, 0x19e10, | ||
1850 | 0x19e50, 0x19f34, | ||
1851 | 0x19f40, 0x19f50, | ||
1852 | 0x19f90, 0x19fe4, | ||
1853 | 0x1a000, 0x1a06c, | ||
1854 | 0x1a0b0, 0x1a120, | ||
1855 | 0x1a128, 0x1a138, | ||
1856 | 0x1a190, 0x1a1c4, | ||
1857 | 0x1a1fc, 0x1a1fc, | ||
1858 | 0x1e008, 0x1e00c, | ||
1859 | 0x1e040, 0x1e04c, | ||
1860 | 0x1e284, 0x1e290, | ||
1861 | 0x1e2c0, 0x1e2c0, | ||
1862 | 0x1e2e0, 0x1e2e0, | ||
1863 | 0x1e300, 0x1e384, | ||
1864 | 0x1e3c0, 0x1e3c8, | ||
1865 | 0x1e408, 0x1e40c, | ||
1866 | 0x1e440, 0x1e44c, | ||
1867 | 0x1e684, 0x1e690, | ||
1868 | 0x1e6c0, 0x1e6c0, | ||
1869 | 0x1e6e0, 0x1e6e0, | ||
1870 | 0x1e700, 0x1e784, | ||
1871 | 0x1e7c0, 0x1e7c8, | ||
1872 | 0x1e808, 0x1e80c, | ||
1873 | 0x1e840, 0x1e84c, | ||
1874 | 0x1ea84, 0x1ea90, | ||
1875 | 0x1eac0, 0x1eac0, | ||
1876 | 0x1eae0, 0x1eae0, | ||
1877 | 0x1eb00, 0x1eb84, | ||
1878 | 0x1ebc0, 0x1ebc8, | ||
1879 | 0x1ec08, 0x1ec0c, | ||
1880 | 0x1ec40, 0x1ec4c, | ||
1881 | 0x1ee84, 0x1ee90, | ||
1882 | 0x1eec0, 0x1eec0, | ||
1883 | 0x1eee0, 0x1eee0, | ||
1884 | 0x1ef00, 0x1ef84, | ||
1885 | 0x1efc0, 0x1efc8, | ||
1886 | 0x1f008, 0x1f00c, | ||
1887 | 0x1f040, 0x1f04c, | ||
1888 | 0x1f284, 0x1f290, | ||
1889 | 0x1f2c0, 0x1f2c0, | ||
1890 | 0x1f2e0, 0x1f2e0, | ||
1891 | 0x1f300, 0x1f384, | ||
1892 | 0x1f3c0, 0x1f3c8, | ||
1893 | 0x1f408, 0x1f40c, | ||
1894 | 0x1f440, 0x1f44c, | ||
1895 | 0x1f684, 0x1f690, | ||
1896 | 0x1f6c0, 0x1f6c0, | ||
1897 | 0x1f6e0, 0x1f6e0, | ||
1898 | 0x1f700, 0x1f784, | ||
1899 | 0x1f7c0, 0x1f7c8, | ||
1900 | 0x1f808, 0x1f80c, | ||
1901 | 0x1f840, 0x1f84c, | ||
1902 | 0x1fa84, 0x1fa90, | ||
1903 | 0x1fac0, 0x1fac0, | ||
1904 | 0x1fae0, 0x1fae0, | ||
1905 | 0x1fb00, 0x1fb84, | ||
1906 | 0x1fbc0, 0x1fbc8, | ||
1907 | 0x1fc08, 0x1fc0c, | ||
1908 | 0x1fc40, 0x1fc4c, | ||
1909 | 0x1fe84, 0x1fe90, | ||
1910 | 0x1fec0, 0x1fec0, | ||
1911 | 0x1fee0, 0x1fee0, | ||
1912 | 0x1ff00, 0x1ff84, | ||
1913 | 0x1ffc0, 0x1ffc8, | ||
1914 | 0x30000, 0x30030, | ||
1915 | 0x30100, 0x30144, | ||
1916 | 0x30190, 0x301d0, | ||
1917 | 0x30200, 0x30318, | ||
1918 | 0x30400, 0x3052c, | ||
1919 | 0x30540, 0x3061c, | ||
1920 | 0x30800, 0x30834, | ||
1921 | 0x308c0, 0x30908, | ||
1922 | 0x30910, 0x309ac, | ||
1923 | 0x30a00, 0x30a04, | ||
1924 | 0x30a0c, 0x30a2c, | ||
1925 | 0x30a44, 0x30a50, | ||
1926 | 0x30a74, 0x30c24, | ||
1927 | 0x30d08, 0x30d14, | ||
1928 | 0x30d1c, 0x30d20, | ||
1929 | 0x30d3c, 0x30d50, | ||
1930 | 0x31200, 0x3120c, | ||
1931 | 0x31220, 0x31220, | ||
1932 | 0x31240, 0x31240, | ||
1933 | 0x31600, 0x31600, | ||
1934 | 0x31608, 0x3160c, | ||
1935 | 0x31a00, 0x31a1c, | ||
1936 | 0x31e04, 0x31e20, | ||
1937 | 0x31e38, 0x31e3c, | ||
1938 | 0x31e80, 0x31e80, | ||
1939 | 0x31e88, 0x31ea8, | ||
1940 | 0x31eb0, 0x31eb4, | ||
1941 | 0x31ec8, 0x31ed4, | ||
1942 | 0x31fb8, 0x32004, | ||
1943 | 0x32208, 0x3223c, | ||
1944 | 0x32600, 0x32630, | ||
1945 | 0x32a00, 0x32abc, | ||
1946 | 0x32b00, 0x32b70, | ||
1947 | 0x33000, 0x33048, | ||
1948 | 0x33060, 0x3309c, | ||
1949 | 0x330f0, 0x33148, | ||
1950 | 0x33160, 0x3319c, | ||
1951 | 0x331f0, 0x332e4, | ||
1952 | 0x332f8, 0x333e4, | ||
1953 | 0x333f8, 0x33448, | ||
1954 | 0x33460, 0x3349c, | ||
1955 | 0x334f0, 0x33548, | ||
1956 | 0x33560, 0x3359c, | ||
1957 | 0x335f0, 0x336e4, | ||
1958 | 0x336f8, 0x337e4, | ||
1959 | 0x337f8, 0x337fc, | ||
1960 | 0x33814, 0x33814, | ||
1961 | 0x3382c, 0x3382c, | ||
1962 | 0x33880, 0x3388c, | ||
1963 | 0x338e8, 0x338ec, | ||
1964 | 0x33900, 0x33948, | ||
1965 | 0x33960, 0x3399c, | ||
1966 | 0x339f0, 0x33ae4, | ||
1967 | 0x33af8, 0x33b10, | ||
1968 | 0x33b28, 0x33b28, | ||
1969 | 0x33b3c, 0x33b50, | ||
1970 | 0x33bf0, 0x33c10, | ||
1971 | 0x33c28, 0x33c28, | ||
1972 | 0x33c3c, 0x33c50, | ||
1973 | 0x33cf0, 0x33cfc, | ||
1974 | 0x34000, 0x34030, | ||
1975 | 0x34100, 0x34144, | ||
1976 | 0x34190, 0x341d0, | ||
1977 | 0x34200, 0x34318, | ||
1978 | 0x34400, 0x3452c, | ||
1979 | 0x34540, 0x3461c, | ||
1980 | 0x34800, 0x34834, | ||
1981 | 0x348c0, 0x34908, | ||
1982 | 0x34910, 0x349ac, | ||
1983 | 0x34a00, 0x34a04, | ||
1984 | 0x34a0c, 0x34a2c, | ||
1985 | 0x34a44, 0x34a50, | ||
1986 | 0x34a74, 0x34c24, | ||
1987 | 0x34d08, 0x34d14, | ||
1988 | 0x34d1c, 0x34d20, | ||
1989 | 0x34d3c, 0x34d50, | ||
1990 | 0x35200, 0x3520c, | ||
1991 | 0x35220, 0x35220, | ||
1992 | 0x35240, 0x35240, | ||
1993 | 0x35600, 0x35600, | ||
1994 | 0x35608, 0x3560c, | ||
1995 | 0x35a00, 0x35a1c, | ||
1996 | 0x35e04, 0x35e20, | ||
1997 | 0x35e38, 0x35e3c, | ||
1998 | 0x35e80, 0x35e80, | ||
1999 | 0x35e88, 0x35ea8, | ||
2000 | 0x35eb0, 0x35eb4, | ||
2001 | 0x35ec8, 0x35ed4, | ||
2002 | 0x35fb8, 0x36004, | ||
2003 | 0x36208, 0x3623c, | ||
2004 | 0x36600, 0x36630, | ||
2005 | 0x36a00, 0x36abc, | ||
2006 | 0x36b00, 0x36b70, | ||
2007 | 0x37000, 0x37048, | ||
2008 | 0x37060, 0x3709c, | ||
2009 | 0x370f0, 0x37148, | ||
2010 | 0x37160, 0x3719c, | ||
2011 | 0x371f0, 0x372e4, | ||
2012 | 0x372f8, 0x373e4, | ||
2013 | 0x373f8, 0x37448, | ||
2014 | 0x37460, 0x3749c, | ||
2015 | 0x374f0, 0x37548, | ||
2016 | 0x37560, 0x3759c, | ||
2017 | 0x375f0, 0x376e4, | ||
2018 | 0x376f8, 0x377e4, | ||
2019 | 0x377f8, 0x377fc, | ||
2020 | 0x37814, 0x37814, | ||
2021 | 0x3782c, 0x3782c, | ||
2022 | 0x37880, 0x3788c, | ||
2023 | 0x378e8, 0x378ec, | ||
2024 | 0x37900, 0x37948, | ||
2025 | 0x37960, 0x3799c, | ||
2026 | 0x379f0, 0x37ae4, | ||
2027 | 0x37af8, 0x37b10, | ||
2028 | 0x37b28, 0x37b28, | ||
2029 | 0x37b3c, 0x37b50, | ||
2030 | 0x37bf0, 0x37c10, | ||
2031 | 0x37c28, 0x37c28, | ||
2032 | 0x37c3c, 0x37c50, | ||
2033 | 0x37cf0, 0x37cfc, | ||
2034 | 0x38000, 0x38030, | ||
2035 | 0x38100, 0x38144, | ||
2036 | 0x38190, 0x381d0, | ||
2037 | 0x38200, 0x38318, | ||
2038 | 0x38400, 0x3852c, | ||
2039 | 0x38540, 0x3861c, | ||
2040 | 0x38800, 0x38834, | ||
2041 | 0x388c0, 0x38908, | ||
2042 | 0x38910, 0x389ac, | ||
2043 | 0x38a00, 0x38a04, | ||
2044 | 0x38a0c, 0x38a2c, | ||
2045 | 0x38a44, 0x38a50, | ||
2046 | 0x38a74, 0x38c24, | ||
2047 | 0x38d08, 0x38d14, | ||
2048 | 0x38d1c, 0x38d20, | ||
2049 | 0x38d3c, 0x38d50, | ||
2050 | 0x39200, 0x3920c, | ||
2051 | 0x39220, 0x39220, | ||
2052 | 0x39240, 0x39240, | ||
2053 | 0x39600, 0x39600, | ||
2054 | 0x39608, 0x3960c, | ||
2055 | 0x39a00, 0x39a1c, | ||
2056 | 0x39e04, 0x39e20, | ||
2057 | 0x39e38, 0x39e3c, | ||
2058 | 0x39e80, 0x39e80, | ||
2059 | 0x39e88, 0x39ea8, | ||
2060 | 0x39eb0, 0x39eb4, | ||
2061 | 0x39ec8, 0x39ed4, | ||
2062 | 0x39fb8, 0x3a004, | ||
2063 | 0x3a208, 0x3a23c, | ||
2064 | 0x3a600, 0x3a630, | ||
2065 | 0x3aa00, 0x3aabc, | ||
2066 | 0x3ab00, 0x3ab70, | ||
2067 | 0x3b000, 0x3b048, | ||
2068 | 0x3b060, 0x3b09c, | ||
2069 | 0x3b0f0, 0x3b148, | ||
2070 | 0x3b160, 0x3b19c, | ||
2071 | 0x3b1f0, 0x3b2e4, | ||
2072 | 0x3b2f8, 0x3b3e4, | ||
2073 | 0x3b3f8, 0x3b448, | ||
2074 | 0x3b460, 0x3b49c, | ||
2075 | 0x3b4f0, 0x3b548, | ||
2076 | 0x3b560, 0x3b59c, | ||
2077 | 0x3b5f0, 0x3b6e4, | ||
2078 | 0x3b6f8, 0x3b7e4, | ||
2079 | 0x3b7f8, 0x3b7fc, | ||
2080 | 0x3b814, 0x3b814, | ||
2081 | 0x3b82c, 0x3b82c, | ||
2082 | 0x3b880, 0x3b88c, | ||
2083 | 0x3b8e8, 0x3b8ec, | ||
2084 | 0x3b900, 0x3b948, | ||
2085 | 0x3b960, 0x3b99c, | ||
2086 | 0x3b9f0, 0x3bae4, | ||
2087 | 0x3baf8, 0x3bb10, | ||
2088 | 0x3bb28, 0x3bb28, | ||
2089 | 0x3bb3c, 0x3bb50, | ||
2090 | 0x3bbf0, 0x3bc10, | ||
2091 | 0x3bc28, 0x3bc28, | ||
2092 | 0x3bc3c, 0x3bc50, | ||
2093 | 0x3bcf0, 0x3bcfc, | ||
2094 | 0x3c000, 0x3c030, | ||
2095 | 0x3c100, 0x3c144, | ||
2096 | 0x3c190, 0x3c1d0, | ||
2097 | 0x3c200, 0x3c318, | ||
2098 | 0x3c400, 0x3c52c, | ||
2099 | 0x3c540, 0x3c61c, | ||
2100 | 0x3c800, 0x3c834, | ||
2101 | 0x3c8c0, 0x3c908, | ||
2102 | 0x3c910, 0x3c9ac, | ||
2103 | 0x3ca00, 0x3ca04, | ||
2104 | 0x3ca0c, 0x3ca2c, | ||
2105 | 0x3ca44, 0x3ca50, | ||
2106 | 0x3ca74, 0x3cc24, | ||
2107 | 0x3cd08, 0x3cd14, | ||
2108 | 0x3cd1c, 0x3cd20, | ||
2109 | 0x3cd3c, 0x3cd50, | ||
2110 | 0x3d200, 0x3d20c, | ||
2111 | 0x3d220, 0x3d220, | ||
2112 | 0x3d240, 0x3d240, | ||
2113 | 0x3d600, 0x3d600, | ||
2114 | 0x3d608, 0x3d60c, | ||
2115 | 0x3da00, 0x3da1c, | ||
2116 | 0x3de04, 0x3de20, | ||
2117 | 0x3de38, 0x3de3c, | ||
2118 | 0x3de80, 0x3de80, | ||
2119 | 0x3de88, 0x3dea8, | ||
2120 | 0x3deb0, 0x3deb4, | ||
2121 | 0x3dec8, 0x3ded4, | ||
2122 | 0x3dfb8, 0x3e004, | ||
2123 | 0x3e208, 0x3e23c, | ||
2124 | 0x3e600, 0x3e630, | ||
2125 | 0x3ea00, 0x3eabc, | ||
2126 | 0x3eb00, 0x3eb70, | ||
2127 | 0x3f000, 0x3f048, | ||
2128 | 0x3f060, 0x3f09c, | ||
2129 | 0x3f0f0, 0x3f148, | ||
2130 | 0x3f160, 0x3f19c, | ||
2131 | 0x3f1f0, 0x3f2e4, | ||
2132 | 0x3f2f8, 0x3f3e4, | ||
2133 | 0x3f3f8, 0x3f448, | ||
2134 | 0x3f460, 0x3f49c, | ||
2135 | 0x3f4f0, 0x3f548, | ||
2136 | 0x3f560, 0x3f59c, | ||
2137 | 0x3f5f0, 0x3f6e4, | ||
2138 | 0x3f6f8, 0x3f7e4, | ||
2139 | 0x3f7f8, 0x3f7fc, | ||
2140 | 0x3f814, 0x3f814, | ||
2141 | 0x3f82c, 0x3f82c, | ||
2142 | 0x3f880, 0x3f88c, | ||
2143 | 0x3f8e8, 0x3f8ec, | ||
2144 | 0x3f900, 0x3f948, | ||
2145 | 0x3f960, 0x3f99c, | ||
2146 | 0x3f9f0, 0x3fae4, | ||
2147 | 0x3faf8, 0x3fb10, | ||
2148 | 0x3fb28, 0x3fb28, | ||
2149 | 0x3fb3c, 0x3fb50, | ||
2150 | 0x3fbf0, 0x3fc10, | ||
2151 | 0x3fc28, 0x3fc28, | ||
2152 | 0x3fc3c, 0x3fc50, | ||
2153 | 0x3fcf0, 0x3fcfc, | ||
2154 | 0x40000, 0x4000c, | ||
2155 | 0x40040, 0x40068, | ||
2156 | 0x40080, 0x40144, | ||
2157 | 0x40180, 0x4018c, | ||
2158 | 0x40200, 0x40298, | ||
2159 | 0x402ac, 0x4033c, | ||
2160 | 0x403f8, 0x403fc, | ||
2161 | 0x41304, 0x413c4, | ||
2162 | 0x41400, 0x4141c, | ||
2163 | 0x41480, 0x414d0, | ||
2164 | 0x44000, 0x44078, | ||
2165 | 0x440c0, 0x44278, | ||
2166 | 0x442c0, 0x44478, | ||
2167 | 0x444c0, 0x44678, | ||
2168 | 0x446c0, 0x44878, | ||
2169 | 0x448c0, 0x449fc, | ||
2170 | 0x45000, 0x45068, | ||
2171 | 0x45080, 0x45084, | ||
2172 | 0x450a0, 0x450b0, | ||
2173 | 0x45200, 0x45268, | ||
2174 | 0x45280, 0x45284, | ||
2175 | 0x452a0, 0x452b0, | ||
2176 | 0x460c0, 0x460e4, | ||
2177 | 0x47000, 0x4708c, | ||
2178 | 0x47200, 0x47250, | ||
2179 | 0x47400, 0x47420, | ||
2180 | 0x47600, 0x47618, | ||
2181 | 0x47800, 0x47814, | ||
2182 | 0x48000, 0x4800c, | ||
2183 | 0x48040, 0x48068, | ||
2184 | 0x48080, 0x48144, | ||
2185 | 0x48180, 0x4818c, | ||
2186 | 0x48200, 0x48298, | ||
2187 | 0x482ac, 0x4833c, | ||
2188 | 0x483f8, 0x483fc, | ||
2189 | 0x49304, 0x493c4, | ||
2190 | 0x49400, 0x4941c, | ||
2191 | 0x49480, 0x494d0, | ||
2192 | 0x4c000, 0x4c078, | ||
2193 | 0x4c0c0, 0x4c278, | ||
2194 | 0x4c2c0, 0x4c478, | ||
2195 | 0x4c4c0, 0x4c678, | ||
2196 | 0x4c6c0, 0x4c878, | ||
2197 | 0x4c8c0, 0x4c9fc, | ||
2198 | 0x4d000, 0x4d068, | ||
2199 | 0x4d080, 0x4d084, | ||
2200 | 0x4d0a0, 0x4d0b0, | ||
2201 | 0x4d200, 0x4d268, | ||
2202 | 0x4d280, 0x4d284, | ||
2203 | 0x4d2a0, 0x4d2b0, | ||
2204 | 0x4e0c0, 0x4e0e4, | ||
2205 | 0x4f000, 0x4f08c, | ||
2206 | 0x4f200, 0x4f250, | ||
2207 | 0x4f400, 0x4f420, | ||
2208 | 0x4f600, 0x4f618, | ||
2209 | 0x4f800, 0x4f814, | ||
2210 | 0x50000, 0x500cc, | ||
2211 | 0x50400, 0x50400, | ||
2212 | 0x50800, 0x508cc, | ||
2213 | 0x50c00, 0x50c00, | ||
2214 | 0x51000, 0x5101c, | ||
2215 | 0x51300, 0x51308, | ||
2216 | }; | ||
2217 | |||
2218 | int i; | ||
2219 | struct adapter *ap = netdev2adap(dev); | ||
2220 | static const unsigned int *reg_ranges; | ||
2221 | int arr_size = 0, buf_size = 0; | ||
2222 | |||
2223 | if (is_t4(ap->params.chip)) { | ||
2224 | reg_ranges = &t4_reg_ranges[0]; | ||
2225 | arr_size = ARRAY_SIZE(t4_reg_ranges); | ||
2226 | buf_size = T4_REGMAP_SIZE; | ||
2227 | } else { | ||
2228 | reg_ranges = &t5_reg_ranges[0]; | ||
2229 | arr_size = ARRAY_SIZE(t5_reg_ranges); | ||
2230 | buf_size = T5_REGMAP_SIZE; | ||
2231 | } | ||
2232 | |||
2233 | regs->version = mk_adap_vers(ap); | ||
2234 | |||
2235 | memset(buf, 0, buf_size); | ||
2236 | for (i = 0; i < arr_size; i += 2) | ||
2237 | reg_block_dump(ap, buf, reg_ranges[i], reg_ranges[i + 1]); | ||
2238 | } | ||
2239 | |||
2240 | static int restart_autoneg(struct net_device *dev) | ||
2241 | { | ||
2242 | struct port_info *p = netdev_priv(dev); | ||
2243 | |||
2244 | if (!netif_running(dev)) | ||
2245 | return -EAGAIN; | ||
2246 | if (p->link_cfg.autoneg != AUTONEG_ENABLE) | ||
2247 | return -EINVAL; | ||
2248 | t4_restart_aneg(p->adapter, p->adapter->fn, p->tx_chan); | ||
2249 | return 0; | ||
2250 | } | ||
2251 | |||
2252 | static int identify_port(struct net_device *dev, | ||
2253 | enum ethtool_phys_id_state state) | ||
2254 | { | ||
2255 | unsigned int val; | ||
2256 | struct adapter *adap = netdev2adap(dev); | ||
2257 | |||
2258 | if (state == ETHTOOL_ID_ACTIVE) | ||
2259 | val = 0xffff; | ||
2260 | else if (state == ETHTOOL_ID_INACTIVE) | ||
2261 | val = 0; | ||
2262 | else | ||
2263 | return -EINVAL; | ||
2264 | |||
2265 | return t4_identify_port(adap, adap->fn, netdev2pinfo(dev)->viid, val); | ||
2266 | } | ||
2267 | |||
2268 | static unsigned int from_fw_linkcaps(enum fw_port_type type, unsigned int caps) | ||
2269 | { | ||
2270 | unsigned int v = 0; | ||
2271 | |||
2272 | if (type == FW_PORT_TYPE_BT_SGMII || type == FW_PORT_TYPE_BT_XFI || | ||
2273 | type == FW_PORT_TYPE_BT_XAUI) { | ||
2274 | v |= SUPPORTED_TP; | ||
2275 | if (caps & FW_PORT_CAP_SPEED_100M) | ||
2276 | v |= SUPPORTED_100baseT_Full; | ||
2277 | if (caps & FW_PORT_CAP_SPEED_1G) | ||
2278 | v |= SUPPORTED_1000baseT_Full; | ||
2279 | if (caps & FW_PORT_CAP_SPEED_10G) | ||
2280 | v |= SUPPORTED_10000baseT_Full; | ||
2281 | } else if (type == FW_PORT_TYPE_KX4 || type == FW_PORT_TYPE_KX) { | ||
2282 | v |= SUPPORTED_Backplane; | ||
2283 | if (caps & FW_PORT_CAP_SPEED_1G) | ||
2284 | v |= SUPPORTED_1000baseKX_Full; | ||
2285 | if (caps & FW_PORT_CAP_SPEED_10G) | ||
2286 | v |= SUPPORTED_10000baseKX4_Full; | ||
2287 | } else if (type == FW_PORT_TYPE_KR) | ||
2288 | v |= SUPPORTED_Backplane | SUPPORTED_10000baseKR_Full; | ||
2289 | else if (type == FW_PORT_TYPE_BP_AP) | ||
2290 | v |= SUPPORTED_Backplane | SUPPORTED_10000baseR_FEC | | ||
2291 | SUPPORTED_10000baseKR_Full | SUPPORTED_1000baseKX_Full; | ||
2292 | else if (type == FW_PORT_TYPE_BP4_AP) | ||
2293 | v |= SUPPORTED_Backplane | SUPPORTED_10000baseR_FEC | | ||
2294 | SUPPORTED_10000baseKR_Full | SUPPORTED_1000baseKX_Full | | ||
2295 | SUPPORTED_10000baseKX4_Full; | ||
2296 | else if (type == FW_PORT_TYPE_FIBER_XFI || | ||
2297 | type == FW_PORT_TYPE_FIBER_XAUI || | ||
2298 | type == FW_PORT_TYPE_SFP || | ||
2299 | type == FW_PORT_TYPE_QSFP_10G || | ||
2300 | type == FW_PORT_TYPE_QSA) { | ||
2301 | v |= SUPPORTED_FIBRE; | ||
2302 | if (caps & FW_PORT_CAP_SPEED_1G) | ||
2303 | v |= SUPPORTED_1000baseT_Full; | ||
2304 | if (caps & FW_PORT_CAP_SPEED_10G) | ||
2305 | v |= SUPPORTED_10000baseT_Full; | ||
2306 | } else if (type == FW_PORT_TYPE_BP40_BA || | ||
2307 | type == FW_PORT_TYPE_QSFP) { | ||
2308 | v |= SUPPORTED_40000baseSR4_Full; | ||
2309 | v |= SUPPORTED_FIBRE; | ||
2310 | } | ||
2311 | |||
2312 | if (caps & FW_PORT_CAP_ANEG) | ||
2313 | v |= SUPPORTED_Autoneg; | ||
2314 | return v; | ||
2315 | } | ||
2316 | |||
2317 | static unsigned int to_fw_linkcaps(unsigned int caps) | ||
2318 | { | ||
2319 | unsigned int v = 0; | ||
2320 | |||
2321 | if (caps & ADVERTISED_100baseT_Full) | ||
2322 | v |= FW_PORT_CAP_SPEED_100M; | ||
2323 | if (caps & ADVERTISED_1000baseT_Full) | ||
2324 | v |= FW_PORT_CAP_SPEED_1G; | ||
2325 | if (caps & ADVERTISED_10000baseT_Full) | ||
2326 | v |= FW_PORT_CAP_SPEED_10G; | ||
2327 | if (caps & ADVERTISED_40000baseSR4_Full) | ||
2328 | v |= FW_PORT_CAP_SPEED_40G; | ||
2329 | return v; | ||
2330 | } | ||
2331 | |||
2332 | static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
2333 | { | ||
2334 | const struct port_info *p = netdev_priv(dev); | ||
2335 | |||
2336 | if (p->port_type == FW_PORT_TYPE_BT_SGMII || | ||
2337 | p->port_type == FW_PORT_TYPE_BT_XFI || | ||
2338 | p->port_type == FW_PORT_TYPE_BT_XAUI) | ||
2339 | cmd->port = PORT_TP; | ||
2340 | else if (p->port_type == FW_PORT_TYPE_FIBER_XFI || | ||
2341 | p->port_type == FW_PORT_TYPE_FIBER_XAUI) | ||
2342 | cmd->port = PORT_FIBRE; | ||
2343 | else if (p->port_type == FW_PORT_TYPE_SFP || | ||
2344 | p->port_type == FW_PORT_TYPE_QSFP_10G || | ||
2345 | p->port_type == FW_PORT_TYPE_QSA || | ||
2346 | p->port_type == FW_PORT_TYPE_QSFP) { | ||
2347 | if (p->mod_type == FW_PORT_MOD_TYPE_LR || | ||
2348 | p->mod_type == FW_PORT_MOD_TYPE_SR || | ||
2349 | p->mod_type == FW_PORT_MOD_TYPE_ER || | ||
2350 | p->mod_type == FW_PORT_MOD_TYPE_LRM) | ||
2351 | cmd->port = PORT_FIBRE; | ||
2352 | else if (p->mod_type == FW_PORT_MOD_TYPE_TWINAX_PASSIVE || | ||
2353 | p->mod_type == FW_PORT_MOD_TYPE_TWINAX_ACTIVE) | ||
2354 | cmd->port = PORT_DA; | ||
2355 | else | ||
2356 | cmd->port = PORT_OTHER; | ||
2357 | } else | ||
2358 | cmd->port = PORT_OTHER; | ||
2359 | |||
2360 | if (p->mdio_addr >= 0) { | ||
2361 | cmd->phy_address = p->mdio_addr; | ||
2362 | cmd->transceiver = XCVR_EXTERNAL; | ||
2363 | cmd->mdio_support = p->port_type == FW_PORT_TYPE_BT_SGMII ? | ||
2364 | MDIO_SUPPORTS_C22 : MDIO_SUPPORTS_C45; | ||
2365 | } else { | ||
2366 | cmd->phy_address = 0; /* not really, but no better option */ | ||
2367 | cmd->transceiver = XCVR_INTERNAL; | ||
2368 | cmd->mdio_support = 0; | ||
2369 | } | ||
2370 | |||
2371 | cmd->supported = from_fw_linkcaps(p->port_type, p->link_cfg.supported); | ||
2372 | cmd->advertising = from_fw_linkcaps(p->port_type, | ||
2373 | p->link_cfg.advertising); | ||
2374 | ethtool_cmd_speed_set(cmd, | ||
2375 | netif_carrier_ok(dev) ? p->link_cfg.speed : 0); | ||
2376 | cmd->duplex = DUPLEX_FULL; | ||
2377 | cmd->autoneg = p->link_cfg.autoneg; | ||
2378 | cmd->maxtxpkt = 0; | ||
2379 | cmd->maxrxpkt = 0; | ||
2380 | return 0; | ||
2381 | } | ||
2382 | |||
2383 | static unsigned int speed_to_caps(int speed) | ||
2384 | { | ||
2385 | if (speed == 100) | ||
2386 | return FW_PORT_CAP_SPEED_100M; | ||
2387 | if (speed == 1000) | ||
2388 | return FW_PORT_CAP_SPEED_1G; | ||
2389 | if (speed == 10000) | ||
2390 | return FW_PORT_CAP_SPEED_10G; | ||
2391 | if (speed == 40000) | ||
2392 | return FW_PORT_CAP_SPEED_40G; | ||
2393 | return 0; | ||
2394 | } | ||
2395 | |||
2396 | static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
2397 | { | ||
2398 | unsigned int cap; | ||
2399 | struct port_info *p = netdev_priv(dev); | ||
2400 | struct link_config *lc = &p->link_cfg; | ||
2401 | u32 speed = ethtool_cmd_speed(cmd); | ||
2402 | |||
2403 | if (cmd->duplex != DUPLEX_FULL) /* only full-duplex supported */ | ||
2404 | return -EINVAL; | ||
2405 | |||
2406 | if (!(lc->supported & FW_PORT_CAP_ANEG)) { | ||
2407 | /* | ||
2408 | * PHY offers a single speed. See if that's what's | ||
2409 | * being requested. | ||
2410 | */ | ||
2411 | if (cmd->autoneg == AUTONEG_DISABLE && | ||
2412 | (lc->supported & speed_to_caps(speed))) | ||
2413 | return 0; | ||
2414 | return -EINVAL; | ||
2415 | } | ||
2416 | |||
2417 | if (cmd->autoneg == AUTONEG_DISABLE) { | ||
2418 | cap = speed_to_caps(speed); | ||
2419 | |||
2420 | if (!(lc->supported & cap) || | ||
2421 | (speed == 1000) || | ||
2422 | (speed == 10000) || | ||
2423 | (speed == 40000)) | ||
2424 | return -EINVAL; | ||
2425 | lc->requested_speed = cap; | ||
2426 | lc->advertising = 0; | ||
2427 | } else { | ||
2428 | cap = to_fw_linkcaps(cmd->advertising); | ||
2429 | if (!(lc->supported & cap)) | ||
2430 | return -EINVAL; | ||
2431 | lc->requested_speed = 0; | ||
2432 | lc->advertising = cap | FW_PORT_CAP_ANEG; | ||
2433 | } | ||
2434 | lc->autoneg = cmd->autoneg; | ||
2435 | |||
2436 | if (netif_running(dev)) | ||
2437 | return t4_link_start(p->adapter, p->adapter->fn, p->tx_chan, | ||
2438 | lc); | ||
2439 | return 0; | ||
2440 | } | ||
2441 | |||
2442 | static void get_pauseparam(struct net_device *dev, | ||
2443 | struct ethtool_pauseparam *epause) | ||
2444 | { | ||
2445 | struct port_info *p = netdev_priv(dev); | ||
2446 | |||
2447 | epause->autoneg = (p->link_cfg.requested_fc & PAUSE_AUTONEG) != 0; | ||
2448 | epause->rx_pause = (p->link_cfg.fc & PAUSE_RX) != 0; | ||
2449 | epause->tx_pause = (p->link_cfg.fc & PAUSE_TX) != 0; | ||
2450 | } | ||
2451 | |||
2452 | static int set_pauseparam(struct net_device *dev, | ||
2453 | struct ethtool_pauseparam *epause) | ||
2454 | { | ||
2455 | struct port_info *p = netdev_priv(dev); | ||
2456 | struct link_config *lc = &p->link_cfg; | ||
2457 | |||
2458 | if (epause->autoneg == AUTONEG_DISABLE) | ||
2459 | lc->requested_fc = 0; | ||
2460 | else if (lc->supported & FW_PORT_CAP_ANEG) | ||
2461 | lc->requested_fc = PAUSE_AUTONEG; | ||
2462 | else | ||
2463 | return -EINVAL; | ||
2464 | |||
2465 | if (epause->rx_pause) | ||
2466 | lc->requested_fc |= PAUSE_RX; | ||
2467 | if (epause->tx_pause) | ||
2468 | lc->requested_fc |= PAUSE_TX; | ||
2469 | if (netif_running(dev)) | ||
2470 | return t4_link_start(p->adapter, p->adapter->fn, p->tx_chan, | ||
2471 | lc); | ||
2472 | return 0; | ||
2473 | } | ||
2474 | |||
2475 | static void get_sge_param(struct net_device *dev, struct ethtool_ringparam *e) | ||
2476 | { | ||
2477 | const struct port_info *pi = netdev_priv(dev); | ||
2478 | const struct sge *s = &pi->adapter->sge; | ||
2479 | |||
2480 | e->rx_max_pending = MAX_RX_BUFFERS; | ||
2481 | e->rx_mini_max_pending = MAX_RSPQ_ENTRIES; | ||
2482 | e->rx_jumbo_max_pending = 0; | ||
2483 | e->tx_max_pending = MAX_TXQ_ENTRIES; | ||
2484 | |||
2485 | e->rx_pending = s->ethrxq[pi->first_qset].fl.size - 8; | ||
2486 | e->rx_mini_pending = s->ethrxq[pi->first_qset].rspq.size; | ||
2487 | e->rx_jumbo_pending = 0; | ||
2488 | e->tx_pending = s->ethtxq[pi->first_qset].q.size; | ||
2489 | } | ||
2490 | |||
2491 | static int set_sge_param(struct net_device *dev, struct ethtool_ringparam *e) | ||
2492 | { | ||
2493 | int i; | ||
2494 | const struct port_info *pi = netdev_priv(dev); | ||
2495 | struct adapter *adapter = pi->adapter; | ||
2496 | struct sge *s = &adapter->sge; | ||
2497 | |||
2498 | if (e->rx_pending > MAX_RX_BUFFERS || e->rx_jumbo_pending || | ||
2499 | e->tx_pending > MAX_TXQ_ENTRIES || | ||
2500 | e->rx_mini_pending > MAX_RSPQ_ENTRIES || | ||
2501 | e->rx_mini_pending < MIN_RSPQ_ENTRIES || | ||
2502 | e->rx_pending < MIN_FL_ENTRIES || e->tx_pending < MIN_TXQ_ENTRIES) | ||
2503 | return -EINVAL; | ||
2504 | |||
2505 | if (adapter->flags & FULL_INIT_DONE) | ||
2506 | return -EBUSY; | ||
2507 | |||
2508 | for (i = 0; i < pi->nqsets; ++i) { | ||
2509 | s->ethtxq[pi->first_qset + i].q.size = e->tx_pending; | ||
2510 | s->ethrxq[pi->first_qset + i].fl.size = e->rx_pending + 8; | ||
2511 | s->ethrxq[pi->first_qset + i].rspq.size = e->rx_mini_pending; | ||
2512 | } | ||
2513 | return 0; | ||
2514 | } | ||
2515 | |||
2516 | static int closest_timer(const struct sge *s, int time) | 1322 | static int closest_timer(const struct sge *s, int time) |
2517 | { | 1323 | { |
2518 | int i, delta, match = 0, min_delta = INT_MAX; | 1324 | int i, delta, match = 0, min_delta = INT_MAX; |
@@ -2545,19 +1351,8 @@ static int closest_thres(const struct sge *s, int thres) | |||
2545 | return match; | 1351 | return match; |
2546 | } | 1352 | } |
2547 | 1353 | ||
2548 | /* | ||
2549 | * Return a queue's interrupt hold-off time in us. 0 means no timer. | ||
2550 | */ | ||
2551 | unsigned int qtimer_val(const struct adapter *adap, | ||
2552 | const struct sge_rspq *q) | ||
2553 | { | ||
2554 | unsigned int idx = q->intr_params >> 1; | ||
2555 | |||
2556 | return idx < SGE_NTIMERS ? adap->sge.timer_val[idx] : 0; | ||
2557 | } | ||
2558 | |||
2559 | /** | 1354 | /** |
2560 | * set_rspq_intr_params - set a queue's interrupt holdoff parameters | 1355 | * cxgb4_set_rspq_intr_params - set a queue's interrupt holdoff parameters |
2561 | * @q: the Rx queue | 1356 | * @q: the Rx queue |
2562 | * @us: the hold-off time in us, or 0 to disable timer | 1357 | * @us: the hold-off time in us, or 0 to disable timer |
2563 | * @cnt: the hold-off packet count, or 0 to disable counter | 1358 | * @cnt: the hold-off packet count, or 0 to disable counter |
@@ -2565,8 +1360,8 @@ unsigned int qtimer_val(const struct adapter *adap, | |||
2565 | * Sets an Rx queue's interrupt hold-off time and packet count. At least | 1360 | * Sets an Rx queue's interrupt hold-off time and packet count. At least |
2566 | * one of the two needs to be enabled for the queue to generate interrupts. | 1361 | * one of the two needs to be enabled for the queue to generate interrupts. |
2567 | */ | 1362 | */ |
2568 | static int set_rspq_intr_params(struct sge_rspq *q, | 1363 | int cxgb4_set_rspq_intr_params(struct sge_rspq *q, |
2569 | unsigned int us, unsigned int cnt) | 1364 | unsigned int us, unsigned int cnt) |
2570 | { | 1365 | { |
2571 | struct adapter *adap = q->adap; | 1366 | struct adapter *adap = q->adap; |
2572 | 1367 | ||
@@ -2597,259 +1392,6 @@ static int set_rspq_intr_params(struct sge_rspq *q, | |||
2597 | return 0; | 1392 | return 0; |
2598 | } | 1393 | } |
2599 | 1394 | ||
2600 | /** | ||
2601 | * set_rx_intr_params - set a net devices's RX interrupt holdoff paramete! | ||
2602 | * @dev: the network device | ||
2603 | * @us: the hold-off time in us, or 0 to disable timer | ||
2604 | * @cnt: the hold-off packet count, or 0 to disable counter | ||
2605 | * | ||
2606 | * Set the RX interrupt hold-off parameters for a network device. | ||
2607 | */ | ||
2608 | static int set_rx_intr_params(struct net_device *dev, | ||
2609 | unsigned int us, unsigned int cnt) | ||
2610 | { | ||
2611 | int i, err; | ||
2612 | struct port_info *pi = netdev_priv(dev); | ||
2613 | struct adapter *adap = pi->adapter; | ||
2614 | struct sge_eth_rxq *q = &adap->sge.ethrxq[pi->first_qset]; | ||
2615 | |||
2616 | for (i = 0; i < pi->nqsets; i++, q++) { | ||
2617 | err = set_rspq_intr_params(&q->rspq, us, cnt); | ||
2618 | if (err) | ||
2619 | return err; | ||
2620 | } | ||
2621 | return 0; | ||
2622 | } | ||
2623 | |||
2624 | static int set_adaptive_rx_setting(struct net_device *dev, int adaptive_rx) | ||
2625 | { | ||
2626 | int i; | ||
2627 | struct port_info *pi = netdev_priv(dev); | ||
2628 | struct adapter *adap = pi->adapter; | ||
2629 | struct sge_eth_rxq *q = &adap->sge.ethrxq[pi->first_qset]; | ||
2630 | |||
2631 | for (i = 0; i < pi->nqsets; i++, q++) | ||
2632 | q->rspq.adaptive_rx = adaptive_rx; | ||
2633 | |||
2634 | return 0; | ||
2635 | } | ||
2636 | |||
2637 | static int get_adaptive_rx_setting(struct net_device *dev) | ||
2638 | { | ||
2639 | struct port_info *pi = netdev_priv(dev); | ||
2640 | struct adapter *adap = pi->adapter; | ||
2641 | struct sge_eth_rxq *q = &adap->sge.ethrxq[pi->first_qset]; | ||
2642 | |||
2643 | return q->rspq.adaptive_rx; | ||
2644 | } | ||
2645 | |||
2646 | static int set_coalesce(struct net_device *dev, struct ethtool_coalesce *c) | ||
2647 | { | ||
2648 | set_adaptive_rx_setting(dev, c->use_adaptive_rx_coalesce); | ||
2649 | return set_rx_intr_params(dev, c->rx_coalesce_usecs, | ||
2650 | c->rx_max_coalesced_frames); | ||
2651 | } | ||
2652 | |||
2653 | static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c) | ||
2654 | { | ||
2655 | const struct port_info *pi = netdev_priv(dev); | ||
2656 | const struct adapter *adap = pi->adapter; | ||
2657 | const struct sge_rspq *rq = &adap->sge.ethrxq[pi->first_qset].rspq; | ||
2658 | |||
2659 | c->rx_coalesce_usecs = qtimer_val(adap, rq); | ||
2660 | c->rx_max_coalesced_frames = (rq->intr_params & QINTR_CNT_EN) ? | ||
2661 | adap->sge.counter_val[rq->pktcnt_idx] : 0; | ||
2662 | c->use_adaptive_rx_coalesce = get_adaptive_rx_setting(dev); | ||
2663 | return 0; | ||
2664 | } | ||
2665 | |||
2666 | /** | ||
2667 | * eeprom_ptov - translate a physical EEPROM address to virtual | ||
2668 | * @phys_addr: the physical EEPROM address | ||
2669 | * @fn: the PCI function number | ||
2670 | * @sz: size of function-specific area | ||
2671 | * | ||
2672 | * Translate a physical EEPROM address to virtual. The first 1K is | ||
2673 | * accessed through virtual addresses starting at 31K, the rest is | ||
2674 | * accessed through virtual addresses starting at 0. | ||
2675 | * | ||
2676 | * The mapping is as follows: | ||
2677 | * [0..1K) -> [31K..32K) | ||
2678 | * [1K..1K+A) -> [31K-A..31K) | ||
2679 | * [1K+A..ES) -> [0..ES-A-1K) | ||
2680 | * | ||
2681 | * where A = @fn * @sz, and ES = EEPROM size. | ||
2682 | */ | ||
2683 | static int eeprom_ptov(unsigned int phys_addr, unsigned int fn, unsigned int sz) | ||
2684 | { | ||
2685 | fn *= sz; | ||
2686 | if (phys_addr < 1024) | ||
2687 | return phys_addr + (31 << 10); | ||
2688 | if (phys_addr < 1024 + fn) | ||
2689 | return 31744 - fn + phys_addr - 1024; | ||
2690 | if (phys_addr < EEPROMSIZE) | ||
2691 | return phys_addr - 1024 - fn; | ||
2692 | return -EINVAL; | ||
2693 | } | ||
2694 | |||
2695 | /* | ||
2696 | * The next two routines implement eeprom read/write from physical addresses. | ||
2697 | */ | ||
2698 | static int eeprom_rd_phys(struct adapter *adap, unsigned int phys_addr, u32 *v) | ||
2699 | { | ||
2700 | int vaddr = eeprom_ptov(phys_addr, adap->fn, EEPROMPFSIZE); | ||
2701 | |||
2702 | if (vaddr >= 0) | ||
2703 | vaddr = pci_read_vpd(adap->pdev, vaddr, sizeof(u32), v); | ||
2704 | return vaddr < 0 ? vaddr : 0; | ||
2705 | } | ||
2706 | |||
2707 | static int eeprom_wr_phys(struct adapter *adap, unsigned int phys_addr, u32 v) | ||
2708 | { | ||
2709 | int vaddr = eeprom_ptov(phys_addr, adap->fn, EEPROMPFSIZE); | ||
2710 | |||
2711 | if (vaddr >= 0) | ||
2712 | vaddr = pci_write_vpd(adap->pdev, vaddr, sizeof(u32), &v); | ||
2713 | return vaddr < 0 ? vaddr : 0; | ||
2714 | } | ||
2715 | |||
2716 | #define EEPROM_MAGIC 0x38E2F10C | ||
2717 | |||
2718 | static int get_eeprom(struct net_device *dev, struct ethtool_eeprom *e, | ||
2719 | u8 *data) | ||
2720 | { | ||
2721 | int i, err = 0; | ||
2722 | struct adapter *adapter = netdev2adap(dev); | ||
2723 | |||
2724 | u8 *buf = kmalloc(EEPROMSIZE, GFP_KERNEL); | ||
2725 | if (!buf) | ||
2726 | return -ENOMEM; | ||
2727 | |||
2728 | e->magic = EEPROM_MAGIC; | ||
2729 | for (i = e->offset & ~3; !err && i < e->offset + e->len; i += 4) | ||
2730 | err = eeprom_rd_phys(adapter, i, (u32 *)&buf[i]); | ||
2731 | |||
2732 | if (!err) | ||
2733 | memcpy(data, buf + e->offset, e->len); | ||
2734 | kfree(buf); | ||
2735 | return err; | ||
2736 | } | ||
2737 | |||
2738 | static int set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, | ||
2739 | u8 *data) | ||
2740 | { | ||
2741 | u8 *buf; | ||
2742 | int err = 0; | ||
2743 | u32 aligned_offset, aligned_len, *p; | ||
2744 | struct adapter *adapter = netdev2adap(dev); | ||
2745 | |||
2746 | if (eeprom->magic != EEPROM_MAGIC) | ||
2747 | return -EINVAL; | ||
2748 | |||
2749 | aligned_offset = eeprom->offset & ~3; | ||
2750 | aligned_len = (eeprom->len + (eeprom->offset & 3) + 3) & ~3; | ||
2751 | |||
2752 | if (adapter->fn > 0) { | ||
2753 | u32 start = 1024 + adapter->fn * EEPROMPFSIZE; | ||
2754 | |||
2755 | if (aligned_offset < start || | ||
2756 | aligned_offset + aligned_len > start + EEPROMPFSIZE) | ||
2757 | return -EPERM; | ||
2758 | } | ||
2759 | |||
2760 | if (aligned_offset != eeprom->offset || aligned_len != eeprom->len) { | ||
2761 | /* | ||
2762 | * RMW possibly needed for first or last words. | ||
2763 | */ | ||
2764 | buf = kmalloc(aligned_len, GFP_KERNEL); | ||
2765 | if (!buf) | ||
2766 | return -ENOMEM; | ||
2767 | err = eeprom_rd_phys(adapter, aligned_offset, (u32 *)buf); | ||
2768 | if (!err && aligned_len > 4) | ||
2769 | err = eeprom_rd_phys(adapter, | ||
2770 | aligned_offset + aligned_len - 4, | ||
2771 | (u32 *)&buf[aligned_len - 4]); | ||
2772 | if (err) | ||
2773 | goto out; | ||
2774 | memcpy(buf + (eeprom->offset & 3), data, eeprom->len); | ||
2775 | } else | ||
2776 | buf = data; | ||
2777 | |||
2778 | err = t4_seeprom_wp(adapter, false); | ||
2779 | if (err) | ||
2780 | goto out; | ||
2781 | |||
2782 | for (p = (u32 *)buf; !err && aligned_len; aligned_len -= 4, p++) { | ||
2783 | err = eeprom_wr_phys(adapter, aligned_offset, *p); | ||
2784 | aligned_offset += 4; | ||
2785 | } | ||
2786 | |||
2787 | if (!err) | ||
2788 | err = t4_seeprom_wp(adapter, true); | ||
2789 | out: | ||
2790 | if (buf != data) | ||
2791 | kfree(buf); | ||
2792 | return err; | ||
2793 | } | ||
2794 | |||
2795 | static int set_flash(struct net_device *netdev, struct ethtool_flash *ef) | ||
2796 | { | ||
2797 | int ret; | ||
2798 | const struct firmware *fw; | ||
2799 | struct adapter *adap = netdev2adap(netdev); | ||
2800 | unsigned int mbox = PCIE_FW_MASTER_M + 1; | ||
2801 | |||
2802 | ef->data[sizeof(ef->data) - 1] = '\0'; | ||
2803 | ret = request_firmware(&fw, ef->data, adap->pdev_dev); | ||
2804 | if (ret < 0) | ||
2805 | return ret; | ||
2806 | |||
2807 | /* If the adapter has been fully initialized then we'll go ahead and | ||
2808 | * try to get the firmware's cooperation in upgrading to the new | ||
2809 | * firmware image otherwise we'll try to do the entire job from the | ||
2810 | * host ... and we always "force" the operation in this path. | ||
2811 | */ | ||
2812 | if (adap->flags & FULL_INIT_DONE) | ||
2813 | mbox = adap->mbox; | ||
2814 | |||
2815 | ret = t4_fw_upgrade(adap, mbox, fw->data, fw->size, 1); | ||
2816 | release_firmware(fw); | ||
2817 | if (!ret) | ||
2818 | dev_info(adap->pdev_dev, "loaded firmware %s," | ||
2819 | " reload cxgb4 driver\n", ef->data); | ||
2820 | return ret; | ||
2821 | } | ||
2822 | |||
2823 | #define WOL_SUPPORTED (WAKE_BCAST | WAKE_MAGIC) | ||
2824 | #define BCAST_CRC 0xa0ccc1a6 | ||
2825 | |||
2826 | static void get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | ||
2827 | { | ||
2828 | wol->supported = WAKE_BCAST | WAKE_MAGIC; | ||
2829 | wol->wolopts = netdev2adap(dev)->wol; | ||
2830 | memset(&wol->sopass, 0, sizeof(wol->sopass)); | ||
2831 | } | ||
2832 | |||
2833 | static int set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | ||
2834 | { | ||
2835 | int err = 0; | ||
2836 | struct port_info *pi = netdev_priv(dev); | ||
2837 | |||
2838 | if (wol->wolopts & ~WOL_SUPPORTED) | ||
2839 | return -EINVAL; | ||
2840 | t4_wol_magic_enable(pi->adapter, pi->tx_chan, | ||
2841 | (wol->wolopts & WAKE_MAGIC) ? dev->dev_addr : NULL); | ||
2842 | if (wol->wolopts & WAKE_BCAST) { | ||
2843 | err = t4_wol_pat_enable(pi->adapter, pi->tx_chan, 0xfe, ~0ULL, | ||
2844 | ~0ULL, 0, false); | ||
2845 | if (!err) | ||
2846 | err = t4_wol_pat_enable(pi->adapter, pi->tx_chan, 1, | ||
2847 | ~6ULL, ~0ULL, BCAST_CRC, true); | ||
2848 | } else | ||
2849 | t4_wol_pat_enable(pi->adapter, pi->tx_chan, 0, 0, 0, 0, false); | ||
2850 | return err; | ||
2851 | } | ||
2852 | |||
2853 | static int cxgb_set_features(struct net_device *dev, netdev_features_t features) | 1395 | static int cxgb_set_features(struct net_device *dev, netdev_features_t features) |
2854 | { | 1396 | { |
2855 | const struct port_info *pi = netdev_priv(dev); | 1397 | const struct port_info *pi = netdev_priv(dev); |
@@ -2867,144 +1409,6 @@ static int cxgb_set_features(struct net_device *dev, netdev_features_t features) | |||
2867 | return err; | 1409 | return err; |
2868 | } | 1410 | } |
2869 | 1411 | ||
2870 | static u32 get_rss_table_size(struct net_device *dev) | ||
2871 | { | ||
2872 | const struct port_info *pi = netdev_priv(dev); | ||
2873 | |||
2874 | return pi->rss_size; | ||
2875 | } | ||
2876 | |||
2877 | static int get_rss_table(struct net_device *dev, u32 *p, u8 *key, u8 *hfunc) | ||
2878 | { | ||
2879 | const struct port_info *pi = netdev_priv(dev); | ||
2880 | unsigned int n = pi->rss_size; | ||
2881 | |||
2882 | if (hfunc) | ||
2883 | *hfunc = ETH_RSS_HASH_TOP; | ||
2884 | if (!p) | ||
2885 | return 0; | ||
2886 | while (n--) | ||
2887 | p[n] = pi->rss[n]; | ||
2888 | return 0; | ||
2889 | } | ||
2890 | |||
2891 | static int set_rss_table(struct net_device *dev, const u32 *p, const u8 *key, | ||
2892 | const u8 hfunc) | ||
2893 | { | ||
2894 | unsigned int i; | ||
2895 | struct port_info *pi = netdev_priv(dev); | ||
2896 | |||
2897 | /* We require at least one supported parameter to be changed and no | ||
2898 | * change in any of the unsupported parameters | ||
2899 | */ | ||
2900 | if (key || | ||
2901 | (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)) | ||
2902 | return -EOPNOTSUPP; | ||
2903 | if (!p) | ||
2904 | return 0; | ||
2905 | |||
2906 | for (i = 0; i < pi->rss_size; i++) | ||
2907 | pi->rss[i] = p[i]; | ||
2908 | if (pi->adapter->flags & FULL_INIT_DONE) | ||
2909 | return write_rss(pi, pi->rss); | ||
2910 | return 0; | ||
2911 | } | ||
2912 | |||
2913 | static int get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info, | ||
2914 | u32 *rules) | ||
2915 | { | ||
2916 | const struct port_info *pi = netdev_priv(dev); | ||
2917 | |||
2918 | switch (info->cmd) { | ||
2919 | case ETHTOOL_GRXFH: { | ||
2920 | unsigned int v = pi->rss_mode; | ||
2921 | |||
2922 | info->data = 0; | ||
2923 | switch (info->flow_type) { | ||
2924 | case TCP_V4_FLOW: | ||
2925 | if (v & FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN_F) | ||
2926 | info->data = RXH_IP_SRC | RXH_IP_DST | | ||
2927 | RXH_L4_B_0_1 | RXH_L4_B_2_3; | ||
2928 | else if (v & FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN_F) | ||
2929 | info->data = RXH_IP_SRC | RXH_IP_DST; | ||
2930 | break; | ||
2931 | case UDP_V4_FLOW: | ||
2932 | if ((v & FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN_F) && | ||
2933 | (v & FW_RSS_VI_CONFIG_CMD_UDPEN_F)) | ||
2934 | info->data = RXH_IP_SRC | RXH_IP_DST | | ||
2935 | RXH_L4_B_0_1 | RXH_L4_B_2_3; | ||
2936 | else if (v & FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN_F) | ||
2937 | info->data = RXH_IP_SRC | RXH_IP_DST; | ||
2938 | break; | ||
2939 | case SCTP_V4_FLOW: | ||
2940 | case AH_ESP_V4_FLOW: | ||
2941 | case IPV4_FLOW: | ||
2942 | if (v & FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN_F) | ||
2943 | info->data = RXH_IP_SRC | RXH_IP_DST; | ||
2944 | break; | ||
2945 | case TCP_V6_FLOW: | ||
2946 | if (v & FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN_F) | ||
2947 | info->data = RXH_IP_SRC | RXH_IP_DST | | ||
2948 | RXH_L4_B_0_1 | RXH_L4_B_2_3; | ||
2949 | else if (v & FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN_F) | ||
2950 | info->data = RXH_IP_SRC | RXH_IP_DST; | ||
2951 | break; | ||
2952 | case UDP_V6_FLOW: | ||
2953 | if ((v & FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN_F) && | ||
2954 | (v & FW_RSS_VI_CONFIG_CMD_UDPEN_F)) | ||
2955 | info->data = RXH_IP_SRC | RXH_IP_DST | | ||
2956 | RXH_L4_B_0_1 | RXH_L4_B_2_3; | ||
2957 | else if (v & FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN_F) | ||
2958 | info->data = RXH_IP_SRC | RXH_IP_DST; | ||
2959 | break; | ||
2960 | case SCTP_V6_FLOW: | ||
2961 | case AH_ESP_V6_FLOW: | ||
2962 | case IPV6_FLOW: | ||
2963 | if (v & FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN_F) | ||
2964 | info->data = RXH_IP_SRC | RXH_IP_DST; | ||
2965 | break; | ||
2966 | } | ||
2967 | return 0; | ||
2968 | } | ||
2969 | case ETHTOOL_GRXRINGS: | ||
2970 | info->data = pi->nqsets; | ||
2971 | return 0; | ||
2972 | } | ||
2973 | return -EOPNOTSUPP; | ||
2974 | } | ||
2975 | |||
2976 | static const struct ethtool_ops cxgb_ethtool_ops = { | ||
2977 | .get_settings = get_settings, | ||
2978 | .set_settings = set_settings, | ||
2979 | .get_drvinfo = get_drvinfo, | ||
2980 | .get_msglevel = get_msglevel, | ||
2981 | .set_msglevel = set_msglevel, | ||
2982 | .get_ringparam = get_sge_param, | ||
2983 | .set_ringparam = set_sge_param, | ||
2984 | .get_coalesce = get_coalesce, | ||
2985 | .set_coalesce = set_coalesce, | ||
2986 | .get_eeprom_len = get_eeprom_len, | ||
2987 | .get_eeprom = get_eeprom, | ||
2988 | .set_eeprom = set_eeprom, | ||
2989 | .get_pauseparam = get_pauseparam, | ||
2990 | .set_pauseparam = set_pauseparam, | ||
2991 | .get_link = ethtool_op_get_link, | ||
2992 | .get_strings = get_strings, | ||
2993 | .set_phys_id = identify_port, | ||
2994 | .nway_reset = restart_autoneg, | ||
2995 | .get_sset_count = get_sset_count, | ||
2996 | .get_ethtool_stats = get_stats, | ||
2997 | .get_regs_len = get_regs_len, | ||
2998 | .get_regs = get_regs, | ||
2999 | .get_wol = get_wol, | ||
3000 | .set_wol = set_wol, | ||
3001 | .get_rxnfc = get_rxnfc, | ||
3002 | .get_rxfh_indir_size = get_rss_table_size, | ||
3003 | .get_rxfh = get_rss_table, | ||
3004 | .set_rxfh = set_rss_table, | ||
3005 | .flash_device = set_flash, | ||
3006 | }; | ||
3007 | |||
3008 | static int setup_debugfs(struct adapter *adap) | 1412 | static int setup_debugfs(struct adapter *adap) |
3009 | { | 1413 | { |
3010 | if (IS_ERR_OR_NULL(adap->debugfs_root)) | 1414 | if (IS_ERR_OR_NULL(adap->debugfs_root)) |
@@ -5689,7 +4093,7 @@ static inline void init_rspq(struct adapter *adap, struct sge_rspq *q, | |||
5689 | unsigned int size, unsigned int iqe_size) | 4093 | unsigned int size, unsigned int iqe_size) |
5690 | { | 4094 | { |
5691 | q->adap = adap; | 4095 | q->adap = adap; |
5692 | set_rspq_intr_params(q, us, cnt); | 4096 | cxgb4_set_rspq_intr_params(q, us, cnt); |
5693 | q->iqe_len = iqe_size; | 4097 | q->iqe_len = iqe_size; |
5694 | q->size = size; | 4098 | q->size = size; |
5695 | } | 4099 | } |
@@ -6184,7 +4588,7 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
6184 | netdev->dcbnl_ops = &cxgb4_dcb_ops; | 4588 | netdev->dcbnl_ops = &cxgb4_dcb_ops; |
6185 | cxgb4_dcb_state_init(netdev); | 4589 | cxgb4_dcb_state_init(netdev); |
6186 | #endif | 4590 | #endif |
6187 | netdev->ethtool_ops = &cxgb_ethtool_ops; | 4591 | cxgb4_set_ethtool_ops(netdev); |
6188 | } | 4592 | } |
6189 | 4593 | ||
6190 | pci_set_drvdata(pdev, adapter); | 4594 | pci_set_drvdata(pdev, adapter); |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 5ed8db977432..5959e3ae72da 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | |||
@@ -625,6 +625,734 @@ int t4_memory_rw(struct adapter *adap, int win, int mtype, u32 addr, | |||
625 | return 0; | 625 | return 0; |
626 | } | 626 | } |
627 | 627 | ||
628 | /** | ||
629 | * t4_get_regs_len - return the size of the chips register set | ||
630 | * @adapter: the adapter | ||
631 | * | ||
632 | * Returns the size of the chip's BAR0 register space. | ||
633 | */ | ||
634 | unsigned int t4_get_regs_len(struct adapter *adapter) | ||
635 | { | ||
636 | unsigned int chip_version = CHELSIO_CHIP_VERSION(adapter->params.chip); | ||
637 | |||
638 | switch (chip_version) { | ||
639 | case CHELSIO_T4: | ||
640 | return T4_REGMAP_SIZE; | ||
641 | |||
642 | case CHELSIO_T5: | ||
643 | return T5_REGMAP_SIZE; | ||
644 | } | ||
645 | |||
646 | dev_err(adapter->pdev_dev, | ||
647 | "Unsupported chip version %d\n", chip_version); | ||
648 | return 0; | ||
649 | } | ||
650 | |||
651 | /** | ||
652 | * t4_get_regs - read chip registers into provided buffer | ||
653 | * @adap: the adapter | ||
654 | * @buf: register buffer | ||
655 | * @buf_size: size (in bytes) of register buffer | ||
656 | * | ||
657 | * If the provided register buffer isn't large enough for the chip's | ||
658 | * full register range, the register dump will be truncated to the | ||
659 | * register buffer's size. | ||
660 | */ | ||
661 | void t4_get_regs(struct adapter *adap, void *buf, size_t buf_size) | ||
662 | { | ||
663 | static const unsigned int t4_reg_ranges[] = { | ||
664 | 0x1008, 0x1108, | ||
665 | 0x1180, 0x11b4, | ||
666 | 0x11fc, 0x123c, | ||
667 | 0x1300, 0x173c, | ||
668 | 0x1800, 0x18fc, | ||
669 | 0x3000, 0x30d8, | ||
670 | 0x30e0, 0x5924, | ||
671 | 0x5960, 0x59d4, | ||
672 | 0x5a00, 0x5af8, | ||
673 | 0x6000, 0x6098, | ||
674 | 0x6100, 0x6150, | ||
675 | 0x6200, 0x6208, | ||
676 | 0x6240, 0x6248, | ||
677 | 0x6280, 0x6338, | ||
678 | 0x6370, 0x638c, | ||
679 | 0x6400, 0x643c, | ||
680 | 0x6500, 0x6524, | ||
681 | 0x6a00, 0x6a38, | ||
682 | 0x6a60, 0x6a78, | ||
683 | 0x6b00, 0x6b84, | ||
684 | 0x6bf0, 0x6c84, | ||
685 | 0x6cf0, 0x6d84, | ||
686 | 0x6df0, 0x6e84, | ||
687 | 0x6ef0, 0x6f84, | ||
688 | 0x6ff0, 0x7084, | ||
689 | 0x70f0, 0x7184, | ||
690 | 0x71f0, 0x7284, | ||
691 | 0x72f0, 0x7384, | ||
692 | 0x73f0, 0x7450, | ||
693 | 0x7500, 0x7530, | ||
694 | 0x7600, 0x761c, | ||
695 | 0x7680, 0x76cc, | ||
696 | 0x7700, 0x7798, | ||
697 | 0x77c0, 0x77fc, | ||
698 | 0x7900, 0x79fc, | ||
699 | 0x7b00, 0x7c38, | ||
700 | 0x7d00, 0x7efc, | ||
701 | 0x8dc0, 0x8e1c, | ||
702 | 0x8e30, 0x8e78, | ||
703 | 0x8ea0, 0x8f6c, | ||
704 | 0x8fc0, 0x9074, | ||
705 | 0x90fc, 0x90fc, | ||
706 | 0x9400, 0x9458, | ||
707 | 0x9600, 0x96bc, | ||
708 | 0x9800, 0x9808, | ||
709 | 0x9820, 0x983c, | ||
710 | 0x9850, 0x9864, | ||
711 | 0x9c00, 0x9c6c, | ||
712 | 0x9c80, 0x9cec, | ||
713 | 0x9d00, 0x9d6c, | ||
714 | 0x9d80, 0x9dec, | ||
715 | 0x9e00, 0x9e6c, | ||
716 | 0x9e80, 0x9eec, | ||
717 | 0x9f00, 0x9f6c, | ||
718 | 0x9f80, 0x9fec, | ||
719 | 0xd004, 0xd03c, | ||
720 | 0xdfc0, 0xdfe0, | ||
721 | 0xe000, 0xea7c, | ||
722 | 0xf000, 0x11110, | ||
723 | 0x11118, 0x11190, | ||
724 | 0x19040, 0x1906c, | ||
725 | 0x19078, 0x19080, | ||
726 | 0x1908c, 0x19124, | ||
727 | 0x19150, 0x191b0, | ||
728 | 0x191d0, 0x191e8, | ||
729 | 0x19238, 0x1924c, | ||
730 | 0x193f8, 0x19474, | ||
731 | 0x19490, 0x194f8, | ||
732 | 0x19800, 0x19f30, | ||
733 | 0x1a000, 0x1a06c, | ||
734 | 0x1a0b0, 0x1a120, | ||
735 | 0x1a128, 0x1a138, | ||
736 | 0x1a190, 0x1a1c4, | ||
737 | 0x1a1fc, 0x1a1fc, | ||
738 | 0x1e040, 0x1e04c, | ||
739 | 0x1e284, 0x1e28c, | ||
740 | 0x1e2c0, 0x1e2c0, | ||
741 | 0x1e2e0, 0x1e2e0, | ||
742 | 0x1e300, 0x1e384, | ||
743 | 0x1e3c0, 0x1e3c8, | ||
744 | 0x1e440, 0x1e44c, | ||
745 | 0x1e684, 0x1e68c, | ||
746 | 0x1e6c0, 0x1e6c0, | ||
747 | 0x1e6e0, 0x1e6e0, | ||
748 | 0x1e700, 0x1e784, | ||
749 | 0x1e7c0, 0x1e7c8, | ||
750 | 0x1e840, 0x1e84c, | ||
751 | 0x1ea84, 0x1ea8c, | ||
752 | 0x1eac0, 0x1eac0, | ||
753 | 0x1eae0, 0x1eae0, | ||
754 | 0x1eb00, 0x1eb84, | ||
755 | 0x1ebc0, 0x1ebc8, | ||
756 | 0x1ec40, 0x1ec4c, | ||
757 | 0x1ee84, 0x1ee8c, | ||
758 | 0x1eec0, 0x1eec0, | ||
759 | 0x1eee0, 0x1eee0, | ||
760 | 0x1ef00, 0x1ef84, | ||
761 | 0x1efc0, 0x1efc8, | ||
762 | 0x1f040, 0x1f04c, | ||
763 | 0x1f284, 0x1f28c, | ||
764 | 0x1f2c0, 0x1f2c0, | ||
765 | 0x1f2e0, 0x1f2e0, | ||
766 | 0x1f300, 0x1f384, | ||
767 | 0x1f3c0, 0x1f3c8, | ||
768 | 0x1f440, 0x1f44c, | ||
769 | 0x1f684, 0x1f68c, | ||
770 | 0x1f6c0, 0x1f6c0, | ||
771 | 0x1f6e0, 0x1f6e0, | ||
772 | 0x1f700, 0x1f784, | ||
773 | 0x1f7c0, 0x1f7c8, | ||
774 | 0x1f840, 0x1f84c, | ||
775 | 0x1fa84, 0x1fa8c, | ||
776 | 0x1fac0, 0x1fac0, | ||
777 | 0x1fae0, 0x1fae0, | ||
778 | 0x1fb00, 0x1fb84, | ||
779 | 0x1fbc0, 0x1fbc8, | ||
780 | 0x1fc40, 0x1fc4c, | ||
781 | 0x1fe84, 0x1fe8c, | ||
782 | 0x1fec0, 0x1fec0, | ||
783 | 0x1fee0, 0x1fee0, | ||
784 | 0x1ff00, 0x1ff84, | ||
785 | 0x1ffc0, 0x1ffc8, | ||
786 | 0x20000, 0x2002c, | ||
787 | 0x20100, 0x2013c, | ||
788 | 0x20190, 0x201c8, | ||
789 | 0x20200, 0x20318, | ||
790 | 0x20400, 0x20528, | ||
791 | 0x20540, 0x20614, | ||
792 | 0x21000, 0x21040, | ||
793 | 0x2104c, 0x21060, | ||
794 | 0x210c0, 0x210ec, | ||
795 | 0x21200, 0x21268, | ||
796 | 0x21270, 0x21284, | ||
797 | 0x212fc, 0x21388, | ||
798 | 0x21400, 0x21404, | ||
799 | 0x21500, 0x21518, | ||
800 | 0x2152c, 0x2153c, | ||
801 | 0x21550, 0x21554, | ||
802 | 0x21600, 0x21600, | ||
803 | 0x21608, 0x21628, | ||
804 | 0x21630, 0x2163c, | ||
805 | 0x21700, 0x2171c, | ||
806 | 0x21780, 0x2178c, | ||
807 | 0x21800, 0x21c38, | ||
808 | 0x21c80, 0x21d7c, | ||
809 | 0x21e00, 0x21e04, | ||
810 | 0x22000, 0x2202c, | ||
811 | 0x22100, 0x2213c, | ||
812 | 0x22190, 0x221c8, | ||
813 | 0x22200, 0x22318, | ||
814 | 0x22400, 0x22528, | ||
815 | 0x22540, 0x22614, | ||
816 | 0x23000, 0x23040, | ||
817 | 0x2304c, 0x23060, | ||
818 | 0x230c0, 0x230ec, | ||
819 | 0x23200, 0x23268, | ||
820 | 0x23270, 0x23284, | ||
821 | 0x232fc, 0x23388, | ||
822 | 0x23400, 0x23404, | ||
823 | 0x23500, 0x23518, | ||
824 | 0x2352c, 0x2353c, | ||
825 | 0x23550, 0x23554, | ||
826 | 0x23600, 0x23600, | ||
827 | 0x23608, 0x23628, | ||
828 | 0x23630, 0x2363c, | ||
829 | 0x23700, 0x2371c, | ||
830 | 0x23780, 0x2378c, | ||
831 | 0x23800, 0x23c38, | ||
832 | 0x23c80, 0x23d7c, | ||
833 | 0x23e00, 0x23e04, | ||
834 | 0x24000, 0x2402c, | ||
835 | 0x24100, 0x2413c, | ||
836 | 0x24190, 0x241c8, | ||
837 | 0x24200, 0x24318, | ||
838 | 0x24400, 0x24528, | ||
839 | 0x24540, 0x24614, | ||
840 | 0x25000, 0x25040, | ||
841 | 0x2504c, 0x25060, | ||
842 | 0x250c0, 0x250ec, | ||
843 | 0x25200, 0x25268, | ||
844 | 0x25270, 0x25284, | ||
845 | 0x252fc, 0x25388, | ||
846 | 0x25400, 0x25404, | ||
847 | 0x25500, 0x25518, | ||
848 | 0x2552c, 0x2553c, | ||
849 | 0x25550, 0x25554, | ||
850 | 0x25600, 0x25600, | ||
851 | 0x25608, 0x25628, | ||
852 | 0x25630, 0x2563c, | ||
853 | 0x25700, 0x2571c, | ||
854 | 0x25780, 0x2578c, | ||
855 | 0x25800, 0x25c38, | ||
856 | 0x25c80, 0x25d7c, | ||
857 | 0x25e00, 0x25e04, | ||
858 | 0x26000, 0x2602c, | ||
859 | 0x26100, 0x2613c, | ||
860 | 0x26190, 0x261c8, | ||
861 | 0x26200, 0x26318, | ||
862 | 0x26400, 0x26528, | ||
863 | 0x26540, 0x26614, | ||
864 | 0x27000, 0x27040, | ||
865 | 0x2704c, 0x27060, | ||
866 | 0x270c0, 0x270ec, | ||
867 | 0x27200, 0x27268, | ||
868 | 0x27270, 0x27284, | ||
869 | 0x272fc, 0x27388, | ||
870 | 0x27400, 0x27404, | ||
871 | 0x27500, 0x27518, | ||
872 | 0x2752c, 0x2753c, | ||
873 | 0x27550, 0x27554, | ||
874 | 0x27600, 0x27600, | ||
875 | 0x27608, 0x27628, | ||
876 | 0x27630, 0x2763c, | ||
877 | 0x27700, 0x2771c, | ||
878 | 0x27780, 0x2778c, | ||
879 | 0x27800, 0x27c38, | ||
880 | 0x27c80, 0x27d7c, | ||
881 | 0x27e00, 0x27e04 | ||
882 | }; | ||
883 | |||
884 | static const unsigned int t5_reg_ranges[] = { | ||
885 | 0x1008, 0x1148, | ||
886 | 0x1180, 0x11b4, | ||
887 | 0x11fc, 0x123c, | ||
888 | 0x1280, 0x173c, | ||
889 | 0x1800, 0x18fc, | ||
890 | 0x3000, 0x3028, | ||
891 | 0x3060, 0x30d8, | ||
892 | 0x30e0, 0x30fc, | ||
893 | 0x3140, 0x357c, | ||
894 | 0x35a8, 0x35cc, | ||
895 | 0x35ec, 0x35ec, | ||
896 | 0x3600, 0x5624, | ||
897 | 0x56cc, 0x575c, | ||
898 | 0x580c, 0x5814, | ||
899 | 0x5890, 0x58bc, | ||
900 | 0x5940, 0x59dc, | ||
901 | 0x59fc, 0x5a18, | ||
902 | 0x5a60, 0x5a9c, | ||
903 | 0x5b9c, 0x5bfc, | ||
904 | 0x6000, 0x6040, | ||
905 | 0x6058, 0x614c, | ||
906 | 0x7700, 0x7798, | ||
907 | 0x77c0, 0x78fc, | ||
908 | 0x7b00, 0x7c54, | ||
909 | 0x7d00, 0x7efc, | ||
910 | 0x8dc0, 0x8de0, | ||
911 | 0x8df8, 0x8e84, | ||
912 | 0x8ea0, 0x8f84, | ||
913 | 0x8fc0, 0x90f8, | ||
914 | 0x9400, 0x9470, | ||
915 | 0x9600, 0x96f4, | ||
916 | 0x9800, 0x9808, | ||
917 | 0x9820, 0x983c, | ||
918 | 0x9850, 0x9864, | ||
919 | 0x9c00, 0x9c6c, | ||
920 | 0x9c80, 0x9cec, | ||
921 | 0x9d00, 0x9d6c, | ||
922 | 0x9d80, 0x9dec, | ||
923 | 0x9e00, 0x9e6c, | ||
924 | 0x9e80, 0x9eec, | ||
925 | 0x9f00, 0x9f6c, | ||
926 | 0x9f80, 0xa020, | ||
927 | 0xd004, 0xd03c, | ||
928 | 0xdfc0, 0xdfe0, | ||
929 | 0xe000, 0x11088, | ||
930 | 0x1109c, 0x11110, | ||
931 | 0x11118, 0x1117c, | ||
932 | 0x11190, 0x11204, | ||
933 | 0x19040, 0x1906c, | ||
934 | 0x19078, 0x19080, | ||
935 | 0x1908c, 0x19124, | ||
936 | 0x19150, 0x191b0, | ||
937 | 0x191d0, 0x191e8, | ||
938 | 0x19238, 0x19290, | ||
939 | 0x193f8, 0x19474, | ||
940 | 0x19490, 0x194cc, | ||
941 | 0x194f0, 0x194f8, | ||
942 | 0x19c00, 0x19c60, | ||
943 | 0x19c94, 0x19e10, | ||
944 | 0x19e50, 0x19f34, | ||
945 | 0x19f40, 0x19f50, | ||
946 | 0x19f90, 0x19fe4, | ||
947 | 0x1a000, 0x1a06c, | ||
948 | 0x1a0b0, 0x1a120, | ||
949 | 0x1a128, 0x1a138, | ||
950 | 0x1a190, 0x1a1c4, | ||
951 | 0x1a1fc, 0x1a1fc, | ||
952 | 0x1e008, 0x1e00c, | ||
953 | 0x1e040, 0x1e04c, | ||
954 | 0x1e284, 0x1e290, | ||
955 | 0x1e2c0, 0x1e2c0, | ||
956 | 0x1e2e0, 0x1e2e0, | ||
957 | 0x1e300, 0x1e384, | ||
958 | 0x1e3c0, 0x1e3c8, | ||
959 | 0x1e408, 0x1e40c, | ||
960 | 0x1e440, 0x1e44c, | ||
961 | 0x1e684, 0x1e690, | ||
962 | 0x1e6c0, 0x1e6c0, | ||
963 | 0x1e6e0, 0x1e6e0, | ||
964 | 0x1e700, 0x1e784, | ||
965 | 0x1e7c0, 0x1e7c8, | ||
966 | 0x1e808, 0x1e80c, | ||
967 | 0x1e840, 0x1e84c, | ||
968 | 0x1ea84, 0x1ea90, | ||
969 | 0x1eac0, 0x1eac0, | ||
970 | 0x1eae0, 0x1eae0, | ||
971 | 0x1eb00, 0x1eb84, | ||
972 | 0x1ebc0, 0x1ebc8, | ||
973 | 0x1ec08, 0x1ec0c, | ||
974 | 0x1ec40, 0x1ec4c, | ||
975 | 0x1ee84, 0x1ee90, | ||
976 | 0x1eec0, 0x1eec0, | ||
977 | 0x1eee0, 0x1eee0, | ||
978 | 0x1ef00, 0x1ef84, | ||
979 | 0x1efc0, 0x1efc8, | ||
980 | 0x1f008, 0x1f00c, | ||
981 | 0x1f040, 0x1f04c, | ||
982 | 0x1f284, 0x1f290, | ||
983 | 0x1f2c0, 0x1f2c0, | ||
984 | 0x1f2e0, 0x1f2e0, | ||
985 | 0x1f300, 0x1f384, | ||
986 | 0x1f3c0, 0x1f3c8, | ||
987 | 0x1f408, 0x1f40c, | ||
988 | 0x1f440, 0x1f44c, | ||
989 | 0x1f684, 0x1f690, | ||
990 | 0x1f6c0, 0x1f6c0, | ||
991 | 0x1f6e0, 0x1f6e0, | ||
992 | 0x1f700, 0x1f784, | ||
993 | 0x1f7c0, 0x1f7c8, | ||
994 | 0x1f808, 0x1f80c, | ||
995 | 0x1f840, 0x1f84c, | ||
996 | 0x1fa84, 0x1fa90, | ||
997 | 0x1fac0, 0x1fac0, | ||
998 | 0x1fae0, 0x1fae0, | ||
999 | 0x1fb00, 0x1fb84, | ||
1000 | 0x1fbc0, 0x1fbc8, | ||
1001 | 0x1fc08, 0x1fc0c, | ||
1002 | 0x1fc40, 0x1fc4c, | ||
1003 | 0x1fe84, 0x1fe90, | ||
1004 | 0x1fec0, 0x1fec0, | ||
1005 | 0x1fee0, 0x1fee0, | ||
1006 | 0x1ff00, 0x1ff84, | ||
1007 | 0x1ffc0, 0x1ffc8, | ||
1008 | 0x30000, 0x30030, | ||
1009 | 0x30100, 0x30144, | ||
1010 | 0x30190, 0x301d0, | ||
1011 | 0x30200, 0x30318, | ||
1012 | 0x30400, 0x3052c, | ||
1013 | 0x30540, 0x3061c, | ||
1014 | 0x30800, 0x30834, | ||
1015 | 0x308c0, 0x30908, | ||
1016 | 0x30910, 0x309ac, | ||
1017 | 0x30a00, 0x30a04, | ||
1018 | 0x30a0c, 0x30a2c, | ||
1019 | 0x30a44, 0x30a50, | ||
1020 | 0x30a74, 0x30c24, | ||
1021 | 0x30d08, 0x30d14, | ||
1022 | 0x30d1c, 0x30d20, | ||
1023 | 0x30d3c, 0x30d50, | ||
1024 | 0x31200, 0x3120c, | ||
1025 | 0x31220, 0x31220, | ||
1026 | 0x31240, 0x31240, | ||
1027 | 0x31600, 0x31600, | ||
1028 | 0x31608, 0x3160c, | ||
1029 | 0x31a00, 0x31a1c, | ||
1030 | 0x31e04, 0x31e20, | ||
1031 | 0x31e38, 0x31e3c, | ||
1032 | 0x31e80, 0x31e80, | ||
1033 | 0x31e88, 0x31ea8, | ||
1034 | 0x31eb0, 0x31eb4, | ||
1035 | 0x31ec8, 0x31ed4, | ||
1036 | 0x31fb8, 0x32004, | ||
1037 | 0x32208, 0x3223c, | ||
1038 | 0x32600, 0x32630, | ||
1039 | 0x32a00, 0x32abc, | ||
1040 | 0x32b00, 0x32b70, | ||
1041 | 0x33000, 0x33048, | ||
1042 | 0x33060, 0x3309c, | ||
1043 | 0x330f0, 0x33148, | ||
1044 | 0x33160, 0x3319c, | ||
1045 | 0x331f0, 0x332e4, | ||
1046 | 0x332f8, 0x333e4, | ||
1047 | 0x333f8, 0x33448, | ||
1048 | 0x33460, 0x3349c, | ||
1049 | 0x334f0, 0x33548, | ||
1050 | 0x33560, 0x3359c, | ||
1051 | 0x335f0, 0x336e4, | ||
1052 | 0x336f8, 0x337e4, | ||
1053 | 0x337f8, 0x337fc, | ||
1054 | 0x33814, 0x33814, | ||
1055 | 0x3382c, 0x3382c, | ||
1056 | 0x33880, 0x3388c, | ||
1057 | 0x338e8, 0x338ec, | ||
1058 | 0x33900, 0x33948, | ||
1059 | 0x33960, 0x3399c, | ||
1060 | 0x339f0, 0x33ae4, | ||
1061 | 0x33af8, 0x33b10, | ||
1062 | 0x33b28, 0x33b28, | ||
1063 | 0x33b3c, 0x33b50, | ||
1064 | 0x33bf0, 0x33c10, | ||
1065 | 0x33c28, 0x33c28, | ||
1066 | 0x33c3c, 0x33c50, | ||
1067 | 0x33cf0, 0x33cfc, | ||
1068 | 0x34000, 0x34030, | ||
1069 | 0x34100, 0x34144, | ||
1070 | 0x34190, 0x341d0, | ||
1071 | 0x34200, 0x34318, | ||
1072 | 0x34400, 0x3452c, | ||
1073 | 0x34540, 0x3461c, | ||
1074 | 0x34800, 0x34834, | ||
1075 | 0x348c0, 0x34908, | ||
1076 | 0x34910, 0x349ac, | ||
1077 | 0x34a00, 0x34a04, | ||
1078 | 0x34a0c, 0x34a2c, | ||
1079 | 0x34a44, 0x34a50, | ||
1080 | 0x34a74, 0x34c24, | ||
1081 | 0x34d08, 0x34d14, | ||
1082 | 0x34d1c, 0x34d20, | ||
1083 | 0x34d3c, 0x34d50, | ||
1084 | 0x35200, 0x3520c, | ||
1085 | 0x35220, 0x35220, | ||
1086 | 0x35240, 0x35240, | ||
1087 | 0x35600, 0x35600, | ||
1088 | 0x35608, 0x3560c, | ||
1089 | 0x35a00, 0x35a1c, | ||
1090 | 0x35e04, 0x35e20, | ||
1091 | 0x35e38, 0x35e3c, | ||
1092 | 0x35e80, 0x35e80, | ||
1093 | 0x35e88, 0x35ea8, | ||
1094 | 0x35eb0, 0x35eb4, | ||
1095 | 0x35ec8, 0x35ed4, | ||
1096 | 0x35fb8, 0x36004, | ||
1097 | 0x36208, 0x3623c, | ||
1098 | 0x36600, 0x36630, | ||
1099 | 0x36a00, 0x36abc, | ||
1100 | 0x36b00, 0x36b70, | ||
1101 | 0x37000, 0x37048, | ||
1102 | 0x37060, 0x3709c, | ||
1103 | 0x370f0, 0x37148, | ||
1104 | 0x37160, 0x3719c, | ||
1105 | 0x371f0, 0x372e4, | ||
1106 | 0x372f8, 0x373e4, | ||
1107 | 0x373f8, 0x37448, | ||
1108 | 0x37460, 0x3749c, | ||
1109 | 0x374f0, 0x37548, | ||
1110 | 0x37560, 0x3759c, | ||
1111 | 0x375f0, 0x376e4, | ||
1112 | 0x376f8, 0x377e4, | ||
1113 | 0x377f8, 0x377fc, | ||
1114 | 0x37814, 0x37814, | ||
1115 | 0x3782c, 0x3782c, | ||
1116 | 0x37880, 0x3788c, | ||
1117 | 0x378e8, 0x378ec, | ||
1118 | 0x37900, 0x37948, | ||
1119 | 0x37960, 0x3799c, | ||
1120 | 0x379f0, 0x37ae4, | ||
1121 | 0x37af8, 0x37b10, | ||
1122 | 0x37b28, 0x37b28, | ||
1123 | 0x37b3c, 0x37b50, | ||
1124 | 0x37bf0, 0x37c10, | ||
1125 | 0x37c28, 0x37c28, | ||
1126 | 0x37c3c, 0x37c50, | ||
1127 | 0x37cf0, 0x37cfc, | ||
1128 | 0x38000, 0x38030, | ||
1129 | 0x38100, 0x38144, | ||
1130 | 0x38190, 0x381d0, | ||
1131 | 0x38200, 0x38318, | ||
1132 | 0x38400, 0x3852c, | ||
1133 | 0x38540, 0x3861c, | ||
1134 | 0x38800, 0x38834, | ||
1135 | 0x388c0, 0x38908, | ||
1136 | 0x38910, 0x389ac, | ||
1137 | 0x38a00, 0x38a04, | ||
1138 | 0x38a0c, 0x38a2c, | ||
1139 | 0x38a44, 0x38a50, | ||
1140 | 0x38a74, 0x38c24, | ||
1141 | 0x38d08, 0x38d14, | ||
1142 | 0x38d1c, 0x38d20, | ||
1143 | 0x38d3c, 0x38d50, | ||
1144 | 0x39200, 0x3920c, | ||
1145 | 0x39220, 0x39220, | ||
1146 | 0x39240, 0x39240, | ||
1147 | 0x39600, 0x39600, | ||
1148 | 0x39608, 0x3960c, | ||
1149 | 0x39a00, 0x39a1c, | ||
1150 | 0x39e04, 0x39e20, | ||
1151 | 0x39e38, 0x39e3c, | ||
1152 | 0x39e80, 0x39e80, | ||
1153 | 0x39e88, 0x39ea8, | ||
1154 | 0x39eb0, 0x39eb4, | ||
1155 | 0x39ec8, 0x39ed4, | ||
1156 | 0x39fb8, 0x3a004, | ||
1157 | 0x3a208, 0x3a23c, | ||
1158 | 0x3a600, 0x3a630, | ||
1159 | 0x3aa00, 0x3aabc, | ||
1160 | 0x3ab00, 0x3ab70, | ||
1161 | 0x3b000, 0x3b048, | ||
1162 | 0x3b060, 0x3b09c, | ||
1163 | 0x3b0f0, 0x3b148, | ||
1164 | 0x3b160, 0x3b19c, | ||
1165 | 0x3b1f0, 0x3b2e4, | ||
1166 | 0x3b2f8, 0x3b3e4, | ||
1167 | 0x3b3f8, 0x3b448, | ||
1168 | 0x3b460, 0x3b49c, | ||
1169 | 0x3b4f0, 0x3b548, | ||
1170 | 0x3b560, 0x3b59c, | ||
1171 | 0x3b5f0, 0x3b6e4, | ||
1172 | 0x3b6f8, 0x3b7e4, | ||
1173 | 0x3b7f8, 0x3b7fc, | ||
1174 | 0x3b814, 0x3b814, | ||
1175 | 0x3b82c, 0x3b82c, | ||
1176 | 0x3b880, 0x3b88c, | ||
1177 | 0x3b8e8, 0x3b8ec, | ||
1178 | 0x3b900, 0x3b948, | ||
1179 | 0x3b960, 0x3b99c, | ||
1180 | 0x3b9f0, 0x3bae4, | ||
1181 | 0x3baf8, 0x3bb10, | ||
1182 | 0x3bb28, 0x3bb28, | ||
1183 | 0x3bb3c, 0x3bb50, | ||
1184 | 0x3bbf0, 0x3bc10, | ||
1185 | 0x3bc28, 0x3bc28, | ||
1186 | 0x3bc3c, 0x3bc50, | ||
1187 | 0x3bcf0, 0x3bcfc, | ||
1188 | 0x3c000, 0x3c030, | ||
1189 | 0x3c100, 0x3c144, | ||
1190 | 0x3c190, 0x3c1d0, | ||
1191 | 0x3c200, 0x3c318, | ||
1192 | 0x3c400, 0x3c52c, | ||
1193 | 0x3c540, 0x3c61c, | ||
1194 | 0x3c800, 0x3c834, | ||
1195 | 0x3c8c0, 0x3c908, | ||
1196 | 0x3c910, 0x3c9ac, | ||
1197 | 0x3ca00, 0x3ca04, | ||
1198 | 0x3ca0c, 0x3ca2c, | ||
1199 | 0x3ca44, 0x3ca50, | ||
1200 | 0x3ca74, 0x3cc24, | ||
1201 | 0x3cd08, 0x3cd14, | ||
1202 | 0x3cd1c, 0x3cd20, | ||
1203 | 0x3cd3c, 0x3cd50, | ||
1204 | 0x3d200, 0x3d20c, | ||
1205 | 0x3d220, 0x3d220, | ||
1206 | 0x3d240, 0x3d240, | ||
1207 | 0x3d600, 0x3d600, | ||
1208 | 0x3d608, 0x3d60c, | ||
1209 | 0x3da00, 0x3da1c, | ||
1210 | 0x3de04, 0x3de20, | ||
1211 | 0x3de38, 0x3de3c, | ||
1212 | 0x3de80, 0x3de80, | ||
1213 | 0x3de88, 0x3dea8, | ||
1214 | 0x3deb0, 0x3deb4, | ||
1215 | 0x3dec8, 0x3ded4, | ||
1216 | 0x3dfb8, 0x3e004, | ||
1217 | 0x3e208, 0x3e23c, | ||
1218 | 0x3e600, 0x3e630, | ||
1219 | 0x3ea00, 0x3eabc, | ||
1220 | 0x3eb00, 0x3eb70, | ||
1221 | 0x3f000, 0x3f048, | ||
1222 | 0x3f060, 0x3f09c, | ||
1223 | 0x3f0f0, 0x3f148, | ||
1224 | 0x3f160, 0x3f19c, | ||
1225 | 0x3f1f0, 0x3f2e4, | ||
1226 | 0x3f2f8, 0x3f3e4, | ||
1227 | 0x3f3f8, 0x3f448, | ||
1228 | 0x3f460, 0x3f49c, | ||
1229 | 0x3f4f0, 0x3f548, | ||
1230 | 0x3f560, 0x3f59c, | ||
1231 | 0x3f5f0, 0x3f6e4, | ||
1232 | 0x3f6f8, 0x3f7e4, | ||
1233 | 0x3f7f8, 0x3f7fc, | ||
1234 | 0x3f814, 0x3f814, | ||
1235 | 0x3f82c, 0x3f82c, | ||
1236 | 0x3f880, 0x3f88c, | ||
1237 | 0x3f8e8, 0x3f8ec, | ||
1238 | 0x3f900, 0x3f948, | ||
1239 | 0x3f960, 0x3f99c, | ||
1240 | 0x3f9f0, 0x3fae4, | ||
1241 | 0x3faf8, 0x3fb10, | ||
1242 | 0x3fb28, 0x3fb28, | ||
1243 | 0x3fb3c, 0x3fb50, | ||
1244 | 0x3fbf0, 0x3fc10, | ||
1245 | 0x3fc28, 0x3fc28, | ||
1246 | 0x3fc3c, 0x3fc50, | ||
1247 | 0x3fcf0, 0x3fcfc, | ||
1248 | 0x40000, 0x4000c, | ||
1249 | 0x40040, 0x40068, | ||
1250 | 0x40080, 0x40144, | ||
1251 | 0x40180, 0x4018c, | ||
1252 | 0x40200, 0x40298, | ||
1253 | 0x402ac, 0x4033c, | ||
1254 | 0x403f8, 0x403fc, | ||
1255 | 0x41304, 0x413c4, | ||
1256 | 0x41400, 0x4141c, | ||
1257 | 0x41480, 0x414d0, | ||
1258 | 0x44000, 0x44078, | ||
1259 | 0x440c0, 0x44278, | ||
1260 | 0x442c0, 0x44478, | ||
1261 | 0x444c0, 0x44678, | ||
1262 | 0x446c0, 0x44878, | ||
1263 | 0x448c0, 0x449fc, | ||
1264 | 0x45000, 0x45068, | ||
1265 | 0x45080, 0x45084, | ||
1266 | 0x450a0, 0x450b0, | ||
1267 | 0x45200, 0x45268, | ||
1268 | 0x45280, 0x45284, | ||
1269 | 0x452a0, 0x452b0, | ||
1270 | 0x460c0, 0x460e4, | ||
1271 | 0x47000, 0x4708c, | ||
1272 | 0x47200, 0x47250, | ||
1273 | 0x47400, 0x47420, | ||
1274 | 0x47600, 0x47618, | ||
1275 | 0x47800, 0x47814, | ||
1276 | 0x48000, 0x4800c, | ||
1277 | 0x48040, 0x48068, | ||
1278 | 0x48080, 0x48144, | ||
1279 | 0x48180, 0x4818c, | ||
1280 | 0x48200, 0x48298, | ||
1281 | 0x482ac, 0x4833c, | ||
1282 | 0x483f8, 0x483fc, | ||
1283 | 0x49304, 0x493c4, | ||
1284 | 0x49400, 0x4941c, | ||
1285 | 0x49480, 0x494d0, | ||
1286 | 0x4c000, 0x4c078, | ||
1287 | 0x4c0c0, 0x4c278, | ||
1288 | 0x4c2c0, 0x4c478, | ||
1289 | 0x4c4c0, 0x4c678, | ||
1290 | 0x4c6c0, 0x4c878, | ||
1291 | 0x4c8c0, 0x4c9fc, | ||
1292 | 0x4d000, 0x4d068, | ||
1293 | 0x4d080, 0x4d084, | ||
1294 | 0x4d0a0, 0x4d0b0, | ||
1295 | 0x4d200, 0x4d268, | ||
1296 | 0x4d280, 0x4d284, | ||
1297 | 0x4d2a0, 0x4d2b0, | ||
1298 | 0x4e0c0, 0x4e0e4, | ||
1299 | 0x4f000, 0x4f08c, | ||
1300 | 0x4f200, 0x4f250, | ||
1301 | 0x4f400, 0x4f420, | ||
1302 | 0x4f600, 0x4f618, | ||
1303 | 0x4f800, 0x4f814, | ||
1304 | 0x50000, 0x500cc, | ||
1305 | 0x50400, 0x50400, | ||
1306 | 0x50800, 0x508cc, | ||
1307 | 0x50c00, 0x50c00, | ||
1308 | 0x51000, 0x5101c, | ||
1309 | 0x51300, 0x51308, | ||
1310 | }; | ||
1311 | |||
1312 | u32 *buf_end = (u32 *)((char *)buf + buf_size); | ||
1313 | const unsigned int *reg_ranges; | ||
1314 | int reg_ranges_size, range; | ||
1315 | unsigned int chip_version = CHELSIO_CHIP_VERSION(adap->params.chip); | ||
1316 | |||
1317 | /* Select the right set of register ranges to dump depending on the | ||
1318 | * adapter chip type. | ||
1319 | */ | ||
1320 | switch (chip_version) { | ||
1321 | case CHELSIO_T4: | ||
1322 | reg_ranges = t4_reg_ranges; | ||
1323 | reg_ranges_size = ARRAY_SIZE(t4_reg_ranges); | ||
1324 | break; | ||
1325 | |||
1326 | case CHELSIO_T5: | ||
1327 | reg_ranges = t5_reg_ranges; | ||
1328 | reg_ranges_size = ARRAY_SIZE(t5_reg_ranges); | ||
1329 | break; | ||
1330 | |||
1331 | default: | ||
1332 | dev_err(adap->pdev_dev, | ||
1333 | "Unsupported chip version %d\n", chip_version); | ||
1334 | return; | ||
1335 | } | ||
1336 | |||
1337 | /* Clear the register buffer and insert the appropriate register | ||
1338 | * values selected by the above register ranges. | ||
1339 | */ | ||
1340 | memset(buf, 0, buf_size); | ||
1341 | for (range = 0; range < reg_ranges_size; range += 2) { | ||
1342 | unsigned int reg = reg_ranges[range]; | ||
1343 | unsigned int last_reg = reg_ranges[range + 1]; | ||
1344 | u32 *bufp = (u32 *)((char *)buf + reg); | ||
1345 | |||
1346 | /* Iterate across the register range filling in the register | ||
1347 | * buffer but don't write past the end of the register buffer. | ||
1348 | */ | ||
1349 | while (reg <= last_reg && bufp < buf_end) { | ||
1350 | *bufp++ = t4_read_reg(adap, reg); | ||
1351 | reg += sizeof(u32); | ||
1352 | } | ||
1353 | } | ||
1354 | } | ||
1355 | |||
628 | #define EEPROM_STAT_ADDR 0x7bfc | 1356 | #define EEPROM_STAT_ADDR 0x7bfc |
629 | #define VPD_BASE 0x400 | 1357 | #define VPD_BASE 0x400 |
630 | #define VPD_BASE_OLD 0 | 1358 | #define VPD_BASE_OLD 0 |