cxgb_main.c revision 1.1.2.2 1 1.1.2.2 uebayasi /**************************************************************************
2 1.1.2.2 uebayasi
3 1.1.2.2 uebayasi Copyright (c) 2007, Chelsio Inc.
4 1.1.2.2 uebayasi All rights reserved.
5 1.1.2.2 uebayasi
6 1.1.2.2 uebayasi Redistribution and use in source and binary forms, with or without
7 1.1.2.2 uebayasi modification, are permitted provided that the following conditions are met:
8 1.1.2.2 uebayasi
9 1.1.2.2 uebayasi 1. Redistributions of source code must retain the above copyright notice,
10 1.1.2.2 uebayasi this list of conditions and the following disclaimer.
11 1.1.2.2 uebayasi
12 1.1.2.2 uebayasi 2. Neither the name of the Chelsio Corporation nor the names of its
13 1.1.2.2 uebayasi contributors may be used to endorse or promote products derived from
14 1.1.2.2 uebayasi this software without specific prior written permission.
15 1.1.2.2 uebayasi
16 1.1.2.2 uebayasi THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 1.1.2.2 uebayasi AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 1.1.2.2 uebayasi IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 1.1.2.2 uebayasi ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 1.1.2.2 uebayasi LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 1.1.2.2 uebayasi CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 1.1.2.2 uebayasi SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 1.1.2.2 uebayasi INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 1.1.2.2 uebayasi CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 1.1.2.2 uebayasi ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 1.1.2.2 uebayasi POSSIBILITY OF SUCH DAMAGE.
27 1.1.2.2 uebayasi
28 1.1.2.2 uebayasi ***************************************************************************/
29 1.1.2.2 uebayasi
30 1.1.2.2 uebayasi #include <sys/cdefs.h>
31 1.1.2.2 uebayasi __KERNEL_RCSID(0, "$NetBSD: cxgb_main.c,v 1.1.2.2 2010/04/30 14:43:44 uebayasi Exp $");
32 1.1.2.2 uebayasi
33 1.1.2.2 uebayasi #include <sys/param.h>
34 1.1.2.2 uebayasi #include <sys/systm.h>
35 1.1.2.2 uebayasi #include <sys/kernel.h>
36 1.1.2.2 uebayasi #include <sys/conf.h>
37 1.1.2.2 uebayasi #include <machine/bus.h>
38 1.1.2.2 uebayasi #include <sys/ioccom.h>
39 1.1.2.2 uebayasi #include <sys/mbuf.h>
40 1.1.2.2 uebayasi #include <sys/socket.h>
41 1.1.2.2 uebayasi #include <sys/sockio.h>
42 1.1.2.2 uebayasi #include <sys/sysctl.h>
43 1.1.2.2 uebayasi #include <sys/queue.h>
44 1.1.2.2 uebayasi
45 1.1.2.2 uebayasi #include <net/bpf.h>
46 1.1.2.2 uebayasi #include <net/if.h>
47 1.1.2.2 uebayasi #include <net/if_arp.h>
48 1.1.2.2 uebayasi #include <net/if_dl.h>
49 1.1.2.2 uebayasi #include <net/if_media.h>
50 1.1.2.2 uebayasi #include <net/if_types.h>
51 1.1.2.2 uebayasi
52 1.1.2.2 uebayasi #include <netinet/in_systm.h>
53 1.1.2.2 uebayasi #include <netinet/in.h>
54 1.1.2.2 uebayasi #include <netinet/ip.h>
55 1.1.2.2 uebayasi #include <netinet/ip.h>
56 1.1.2.2 uebayasi #include <netinet/tcp.h>
57 1.1.2.2 uebayasi #include <netinet/udp.h>
58 1.1.2.2 uebayasi #include <netinet/if_inarp.h>
59 1.1.2.2 uebayasi
60 1.1.2.2 uebayasi #include <dev/pci/pcireg.h>
61 1.1.2.2 uebayasi #include <dev/pci/pcivar.h>
62 1.1.2.2 uebayasi
63 1.1.2.2 uebayasi #ifdef CONFIG_DEFINED
64 1.1.2.2 uebayasi #include <cxgb_include.h>
65 1.1.2.2 uebayasi #else
66 1.1.2.2 uebayasi #include <dev/pci/cxgb/cxgb_include.h>
67 1.1.2.2 uebayasi #endif
68 1.1.2.2 uebayasi
69 1.1.2.2 uebayasi #ifdef PRIV_SUPPORTED
70 1.1.2.2 uebayasi #include <sys/priv.h>
71 1.1.2.2 uebayasi #endif
72 1.1.2.2 uebayasi
73 1.1.2.2 uebayasi #include <altq/altq_conf.h>
74 1.1.2.2 uebayasi
75 1.1.2.2 uebayasi static int cxgb_setup_msix(adapter_t *, int);
76 1.1.2.2 uebayasi static void cxgb_teardown_msix(adapter_t *);
77 1.1.2.2 uebayasi static int cxgb_init(struct ifnet *);
78 1.1.2.2 uebayasi static void cxgb_init_locked(struct port_info *);
79 1.1.2.2 uebayasi static void cxgb_stop_locked(struct port_info *);
80 1.1.2.2 uebayasi static void cxgb_set_rxmode(struct port_info *);
81 1.1.2.2 uebayasi static int cxgb_ioctl(struct ifnet *, unsigned long, void *);
82 1.1.2.2 uebayasi static void cxgb_start(struct ifnet *);
83 1.1.2.2 uebayasi static void cxgb_stop(struct ifnet *, int);
84 1.1.2.2 uebayasi static void cxgb_start_proc(struct work *, void *);
85 1.1.2.2 uebayasi static int cxgb_media_change(struct ifnet *);
86 1.1.2.2 uebayasi static void cxgb_media_status(struct ifnet *, struct ifmediareq *);
87 1.1.2.2 uebayasi static int setup_sge_qsets(adapter_t *);
88 1.1.2.2 uebayasi static int cxgb_async_intr(void *);
89 1.1.2.2 uebayasi static void cxgb_ext_intr_handler(struct work *, void *);
90 1.1.2.2 uebayasi static void cxgb_tick_handler(struct work *, void *);
91 1.1.2.2 uebayasi static void cxgb_down_locked(struct adapter *sc);
92 1.1.2.2 uebayasi static void cxgb_tick(void *);
93 1.1.2.2 uebayasi static void setup_rss(adapter_t *sc);
94 1.1.2.2 uebayasi
95 1.1.2.2 uebayasi /* Attachment glue for the PCI controller end of the device. Each port of
96 1.1.2.2 uebayasi * the device is attached separately, as defined later.
97 1.1.2.2 uebayasi */
98 1.1.2.2 uebayasi static int cxgb_controller_match(device_t dev, cfdata_t match, void *context);
99 1.1.2.2 uebayasi static void cxgb_controller_attach(device_t parent, device_t dev, void *context);
100 1.1.2.2 uebayasi static int cxgb_controller_detach(device_t dev, int flags);
101 1.1.2.2 uebayasi static void cxgb_free(struct adapter *);
102 1.1.2.2 uebayasi static __inline void reg_block_dump(struct adapter *ap, uint8_t *buf, unsigned int start,
103 1.1.2.2 uebayasi unsigned int end);
104 1.1.2.2 uebayasi static void touch_bars(device_t dev);
105 1.1.2.2 uebayasi
106 1.1.2.2 uebayasi #ifdef notyet
107 1.1.2.2 uebayasi static int offload_close(struct toedev *tdev);
108 1.1.2.2 uebayasi #endif
109 1.1.2.2 uebayasi
110 1.1.2.2 uebayasi
111 1.1.2.2 uebayasi CFATTACH_DECL(cxgbc, sizeof(struct adapter), cxgb_controller_match, cxgb_controller_attach, cxgb_controller_detach, NULL);
112 1.1.2.2 uebayasi
113 1.1.2.2 uebayasi /*
114 1.1.2.2 uebayasi * Attachment glue for the ports. Attachment is done directly to the
115 1.1.2.2 uebayasi * controller device.
116 1.1.2.2 uebayasi */
117 1.1.2.2 uebayasi static int cxgb_port_match(device_t dev, cfdata_t match, void *context);
118 1.1.2.2 uebayasi static void cxgb_port_attach(device_t dev, device_t self, void *context);
119 1.1.2.2 uebayasi static int cxgb_port_detach(device_t dev, int flags);
120 1.1.2.2 uebayasi
121 1.1.2.2 uebayasi CFATTACH_DECL(cxgb, sizeof(struct port_device), cxgb_port_match, cxgb_port_attach, cxgb_port_detach, NULL);
122 1.1.2.2 uebayasi
123 1.1.2.2 uebayasi #define SGE_MSIX_COUNT (SGE_QSETS + 1)
124 1.1.2.2 uebayasi
125 1.1.2.2 uebayasi extern int collapse_mbufs;
126 1.1.2.2 uebayasi #ifdef MSI_SUPPORTED
127 1.1.2.2 uebayasi /*
128 1.1.2.2 uebayasi * The driver uses the best interrupt scheme available on a platform in the
129 1.1.2.2 uebayasi * order MSI-X, MSI, legacy pin interrupts. This parameter determines which
130 1.1.2.2 uebayasi * of these schemes the driver may consider as follows:
131 1.1.2.2 uebayasi *
132 1.1.2.2 uebayasi * msi = 2: choose from among all three options
133 1.1.2.2 uebayasi * msi = 1 : only consider MSI and pin interrupts
134 1.1.2.2 uebayasi * msi = 0: force pin interrupts
135 1.1.2.2 uebayasi */
136 1.1.2.2 uebayasi static int msi_allowed = 2;
137 1.1.2.2 uebayasi #endif
138 1.1.2.2 uebayasi
139 1.1.2.2 uebayasi /*
140 1.1.2.2 uebayasi * The driver uses an auto-queue algorithm by default.
141 1.1.2.2 uebayasi * To disable it and force a single queue-set per port, use singleq = 1.
142 1.1.2.2 uebayasi */
143 1.1.2.2 uebayasi static int singleq = 1;
144 1.1.2.2 uebayasi
145 1.1.2.2 uebayasi enum {
146 1.1.2.2 uebayasi MAX_TXQ_ENTRIES = 16384,
147 1.1.2.2 uebayasi MAX_CTRL_TXQ_ENTRIES = 1024,
148 1.1.2.2 uebayasi MAX_RSPQ_ENTRIES = 16384,
149 1.1.2.2 uebayasi MAX_RX_BUFFERS = 16384,
150 1.1.2.2 uebayasi MAX_RX_JUMBO_BUFFERS = 16384,
151 1.1.2.2 uebayasi MIN_TXQ_ENTRIES = 4,
152 1.1.2.2 uebayasi MIN_CTRL_TXQ_ENTRIES = 4,
153 1.1.2.2 uebayasi MIN_RSPQ_ENTRIES = 32,
154 1.1.2.2 uebayasi MIN_FL_ENTRIES = 32,
155 1.1.2.2 uebayasi MIN_FL_JUMBO_ENTRIES = 32
156 1.1.2.2 uebayasi };
157 1.1.2.2 uebayasi
158 1.1.2.2 uebayasi struct filter_info {
159 1.1.2.2 uebayasi u32 sip;
160 1.1.2.2 uebayasi u32 sip_mask;
161 1.1.2.2 uebayasi u32 dip;
162 1.1.2.2 uebayasi u16 sport;
163 1.1.2.2 uebayasi u16 dport;
164 1.1.2.2 uebayasi u32 vlan:12;
165 1.1.2.2 uebayasi u32 vlan_prio:3;
166 1.1.2.2 uebayasi u32 mac_hit:1;
167 1.1.2.2 uebayasi u32 mac_idx:4;
168 1.1.2.2 uebayasi u32 mac_vld:1;
169 1.1.2.2 uebayasi u32 pkt_type:2;
170 1.1.2.2 uebayasi u32 report_filter_id:1;
171 1.1.2.2 uebayasi u32 pass:1;
172 1.1.2.2 uebayasi u32 rss:1;
173 1.1.2.2 uebayasi u32 qset:3;
174 1.1.2.2 uebayasi u32 locked:1;
175 1.1.2.2 uebayasi u32 valid:1;
176 1.1.2.2 uebayasi };
177 1.1.2.2 uebayasi
178 1.1.2.2 uebayasi enum { FILTER_NO_VLAN_PRI = 7 };
179 1.1.2.2 uebayasi
180 1.1.2.2 uebayasi #define PORT_MASK ((1 << MAX_NPORTS) - 1)
181 1.1.2.2 uebayasi
182 1.1.2.2 uebayasi /* Table for probing the cards. The desc field isn't actually used */
183 1.1.2.2 uebayasi struct cxgb_ident {
184 1.1.2.2 uebayasi uint16_t vendor;
185 1.1.2.2 uebayasi uint16_t device;
186 1.1.2.2 uebayasi int index;
187 1.1.2.2 uebayasi const char *desc;
188 1.1.2.2 uebayasi } cxgb_identifiers[] = {
189 1.1.2.2 uebayasi {PCI_VENDOR_ID_CHELSIO, 0x0020, 0, "PE9000"},
190 1.1.2.2 uebayasi {PCI_VENDOR_ID_CHELSIO, 0x0021, 1, "T302E"},
191 1.1.2.2 uebayasi {PCI_VENDOR_ID_CHELSIO, 0x0022, 2, "T310E"},
192 1.1.2.2 uebayasi {PCI_VENDOR_ID_CHELSIO, 0x0023, 3, "T320X"},
193 1.1.2.2 uebayasi {PCI_VENDOR_ID_CHELSIO, 0x0024, 1, "T302X"},
194 1.1.2.2 uebayasi {PCI_VENDOR_ID_CHELSIO, 0x0025, 3, "T320E"},
195 1.1.2.2 uebayasi {PCI_VENDOR_ID_CHELSIO, 0x0026, 2, "T310X"},
196 1.1.2.2 uebayasi {PCI_VENDOR_ID_CHELSIO, 0x0030, 2, "T3B10"},
197 1.1.2.2 uebayasi {PCI_VENDOR_ID_CHELSIO, 0x0031, 3, "T3B20"},
198 1.1.2.2 uebayasi {PCI_VENDOR_ID_CHELSIO, 0x0032, 1, "T3B02"},
199 1.1.2.2 uebayasi {PCI_VENDOR_ID_CHELSIO, 0x0033, 4, "T3B04"},
200 1.1.2.2 uebayasi {0, 0, 0, NULL}
201 1.1.2.2 uebayasi };
202 1.1.2.2 uebayasi
203 1.1.2.2 uebayasi
204 1.1.2.2 uebayasi static inline char
205 1.1.2.2 uebayasi t3rev2char(struct adapter *adapter)
206 1.1.2.2 uebayasi {
207 1.1.2.2 uebayasi char rev = 'z';
208 1.1.2.2 uebayasi
209 1.1.2.2 uebayasi switch(adapter->params.rev) {
210 1.1.2.2 uebayasi case T3_REV_A:
211 1.1.2.2 uebayasi rev = 'a';
212 1.1.2.2 uebayasi break;
213 1.1.2.2 uebayasi case T3_REV_B:
214 1.1.2.2 uebayasi case T3_REV_B2:
215 1.1.2.2 uebayasi rev = 'b';
216 1.1.2.2 uebayasi break;
217 1.1.2.2 uebayasi case T3_REV_C:
218 1.1.2.2 uebayasi rev = 'c';
219 1.1.2.2 uebayasi break;
220 1.1.2.2 uebayasi }
221 1.1.2.2 uebayasi return rev;
222 1.1.2.2 uebayasi }
223 1.1.2.2 uebayasi
224 1.1.2.2 uebayasi static struct cxgb_ident *cxgb_get_ident(struct pci_attach_args *pa)
225 1.1.2.2 uebayasi {
226 1.1.2.2 uebayasi struct cxgb_ident *id;
227 1.1.2.2 uebayasi int vendorid, deviceid;
228 1.1.2.2 uebayasi
229 1.1.2.2 uebayasi vendorid = PCI_VENDOR(pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ID_REG));
230 1.1.2.2 uebayasi deviceid = PCI_PRODUCT(pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ID_REG));
231 1.1.2.2 uebayasi
232 1.1.2.2 uebayasi for (id = cxgb_identifiers; id->desc != NULL; id++) {
233 1.1.2.2 uebayasi if ((id->vendor == vendorid) &&
234 1.1.2.2 uebayasi (id->device == deviceid)) {
235 1.1.2.2 uebayasi return (id);
236 1.1.2.2 uebayasi }
237 1.1.2.2 uebayasi }
238 1.1.2.2 uebayasi return (NULL);
239 1.1.2.2 uebayasi }
240 1.1.2.2 uebayasi
241 1.1.2.2 uebayasi static const struct adapter_info *cxgb_get_adapter_info(struct pci_attach_args *pa)
242 1.1.2.2 uebayasi {
243 1.1.2.2 uebayasi struct cxgb_ident *id;
244 1.1.2.2 uebayasi const struct adapter_info *ai;
245 1.1.2.2 uebayasi
246 1.1.2.2 uebayasi id = cxgb_get_ident(pa);
247 1.1.2.2 uebayasi if (id == NULL)
248 1.1.2.2 uebayasi return (NULL);
249 1.1.2.2 uebayasi
250 1.1.2.2 uebayasi ai = t3_get_adapter_info(id->index);
251 1.1.2.2 uebayasi return (ai);
252 1.1.2.2 uebayasi }
253 1.1.2.2 uebayasi
254 1.1.2.2 uebayasi static int cxgb_controller_match(device_t dev, cfdata_t match, void *context)
255 1.1.2.2 uebayasi {
256 1.1.2.2 uebayasi struct pci_attach_args *pa = context;
257 1.1.2.2 uebayasi const struct adapter_info *ai;
258 1.1.2.2 uebayasi
259 1.1.2.2 uebayasi ai = cxgb_get_adapter_info(pa);
260 1.1.2.2 uebayasi if (ai == NULL)
261 1.1.2.2 uebayasi return (0);
262 1.1.2.2 uebayasi
263 1.1.2.2 uebayasi return (100); // we ARE the best driver for this card!!
264 1.1.2.2 uebayasi }
265 1.1.2.2 uebayasi
266 1.1.2.2 uebayasi #define FW_FNAME "t3fw%d%d%d"
267 1.1.2.2 uebayasi #define TPEEPROM_NAME "t3%ctpe%d%d%d"
268 1.1.2.2 uebayasi #define TPSRAM_NAME "t3%cps%d%d%d"
269 1.1.2.2 uebayasi
270 1.1.2.2 uebayasi int cxgb_cfprint(void *aux, const char *info);
271 1.1.2.2 uebayasi int cxgb_cfprint(void *aux, const char *info)
272 1.1.2.2 uebayasi {
273 1.1.2.2 uebayasi if (info)
274 1.1.2.2 uebayasi {
275 1.1.2.2 uebayasi printf("cxgb_cfprint(%p, \"%s\")\n", aux, info);
276 1.1.2.2 uebayasi INT3;
277 1.1.2.2 uebayasi }
278 1.1.2.2 uebayasi
279 1.1.2.2 uebayasi return (QUIET);
280 1.1.2.2 uebayasi }
281 1.1.2.2 uebayasi
282 1.1.2.2 uebayasi void cxgb_make_task(void *context)
283 1.1.2.2 uebayasi {
284 1.1.2.2 uebayasi struct cxgb_task *w = (struct cxgb_task *)context;
285 1.1.2.2 uebayasi
286 1.1.2.2 uebayasi // we can only use workqueue_create() once the system is up and running
287 1.1.2.2 uebayasi workqueue_create(&w->wq, w->name, w->func, w->context, PRIBIO, IPL_NET, 0);
288 1.1.2.2 uebayasi // printf("======>> create workqueue for %s %p\n", w->name, w->wq);
289 1.1.2.2 uebayasi }
290 1.1.2.2 uebayasi
291 1.1.2.2 uebayasi static void
292 1.1.2.2 uebayasi cxgb_controller_attach(device_t parent, device_t dev, void *context)
293 1.1.2.2 uebayasi {
294 1.1.2.2 uebayasi device_t child;
295 1.1.2.2 uebayasi const struct adapter_info *ai;
296 1.1.2.2 uebayasi struct adapter *sc;
297 1.1.2.2 uebayasi struct pci_attach_args *pa = context;
298 1.1.2.2 uebayasi struct cxgb_attach_args cxgb_args;
299 1.1.2.2 uebayasi int locs[2];
300 1.1.2.2 uebayasi int i, error = 0;
301 1.1.2.2 uebayasi uint32_t vers;
302 1.1.2.2 uebayasi int port_qsets = 1;
303 1.1.2.2 uebayasi int reg;
304 1.1.2.2 uebayasi #ifdef MSI_SUPPORTED
305 1.1.2.2 uebayasi int msi_needed;
306 1.1.2.2 uebayasi #endif
307 1.1.2.2 uebayasi
308 1.1.2.2 uebayasi sc = device_private(dev);
309 1.1.2.2 uebayasi sc->dev = dev;
310 1.1.2.2 uebayasi memcpy(&sc->pa, pa, sizeof(struct pci_attach_args));
311 1.1.2.2 uebayasi sc->msi_count = 0;
312 1.1.2.2 uebayasi ai = cxgb_get_adapter_info(pa);
313 1.1.2.2 uebayasi
314 1.1.2.2 uebayasi /*
315 1.1.2.2 uebayasi * XXX not really related but a recent addition
316 1.1.2.2 uebayasi */
317 1.1.2.2 uebayasi #ifdef MSI_SUPPORTED
318 1.1.2.2 uebayasi /* find the PCIe link width and set max read request to 4KB*/
319 1.1.2.2 uebayasi if (pci_find_extcap(dev, PCIY_EXPRESS, ®) == 0) {
320 1.1.2.2 uebayasi uint16_t lnk, pectl;
321 1.1.2.2 uebayasi lnk = pci_read_config(dev, reg + 0x12, 2);
322 1.1.2.2 uebayasi sc->link_width = (lnk >> 4) & 0x3f;
323 1.1.2.2 uebayasi
324 1.1.2.2 uebayasi pectl = pci_read_config(dev, reg + 0x8, 2);
325 1.1.2.2 uebayasi pectl = (pectl & ~0x7000) | (5 << 12);
326 1.1.2.2 uebayasi pci_write_config(dev, reg + 0x8, pectl, 2);
327 1.1.2.2 uebayasi }
328 1.1.2.2 uebayasi
329 1.1.2.2 uebayasi if (sc->link_width != 0 && sc->link_width <= 4 &&
330 1.1.2.2 uebayasi (ai->nports0 + ai->nports1) <= 2) {
331 1.1.2.2 uebayasi device_printf(sc->dev,
332 1.1.2.2 uebayasi "PCIe x%d Link, expect reduced performance\n",
333 1.1.2.2 uebayasi sc->link_width);
334 1.1.2.2 uebayasi }
335 1.1.2.2 uebayasi #endif
336 1.1.2.2 uebayasi
337 1.1.2.2 uebayasi touch_bars(dev);
338 1.1.2.2 uebayasi
339 1.1.2.2 uebayasi pci_enable_busmaster(dev);
340 1.1.2.2 uebayasi
341 1.1.2.2 uebayasi /*
342 1.1.2.2 uebayasi * Allocate the registers and make them available to the driver.
343 1.1.2.2 uebayasi * The registers that we care about for NIC mode are in BAR 0
344 1.1.2.2 uebayasi */
345 1.1.2.2 uebayasi sc->regs_rid = PCI_MAPREG_START;
346 1.1.2.2 uebayasi t3_os_pci_read_config_4(sc, PCI_MAPREG_START, ®);
347 1.1.2.2 uebayasi
348 1.1.2.2 uebayasi // call bus_space_map
349 1.1.2.2 uebayasi sc->bar0 = reg&0xFFFFF000;
350 1.1.2.2 uebayasi bus_space_map(sc->pa.pa_memt, sc->bar0, 4096, 0, &sc->bar0_handle);
351 1.1.2.2 uebayasi
352 1.1.2.2 uebayasi MTX_INIT(&sc->sge.reg_lock, sc->reglockbuf, NULL, MTX_DEF);
353 1.1.2.2 uebayasi MTX_INIT(&sc->mdio_lock, sc->mdiolockbuf, NULL, MTX_DEF);
354 1.1.2.2 uebayasi MTX_INIT(&sc->elmer_lock, sc->elmerlockbuf, NULL, MTX_DEF);
355 1.1.2.2 uebayasi
356 1.1.2.2 uebayasi sc->bt = sc->pa.pa_memt;
357 1.1.2.2 uebayasi sc->bh = sc->bar0_handle;
358 1.1.2.2 uebayasi sc->mmio_len = 4096;
359 1.1.2.2 uebayasi
360 1.1.2.2 uebayasi if (t3_prep_adapter(sc, ai, 1) < 0) {
361 1.1.2.2 uebayasi printf("prep adapter failed\n");
362 1.1.2.2 uebayasi error = ENODEV;
363 1.1.2.2 uebayasi goto out;
364 1.1.2.2 uebayasi }
365 1.1.2.2 uebayasi /* Allocate the BAR for doing MSI-X. If it succeeds, try to allocate
366 1.1.2.2 uebayasi * enough messages for the queue sets. If that fails, try falling
367 1.1.2.2 uebayasi * back to MSI. If that fails, then try falling back to the legacy
368 1.1.2.2 uebayasi * interrupt pin model.
369 1.1.2.2 uebayasi */
370 1.1.2.2 uebayasi #ifdef MSI_SUPPORTED
371 1.1.2.2 uebayasi
372 1.1.2.2 uebayasi sc->msix_regs_rid = 0x20;
373 1.1.2.2 uebayasi if ((msi_allowed >= 2) &&
374 1.1.2.2 uebayasi (sc->msix_regs_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
375 1.1.2.2 uebayasi &sc->msix_regs_rid, RF_ACTIVE)) != NULL) {
376 1.1.2.2 uebayasi
377 1.1.2.2 uebayasi msi_needed = sc->msi_count = SGE_MSIX_COUNT;
378 1.1.2.2 uebayasi
379 1.1.2.2 uebayasi if (((error = pci_alloc_msix(dev, &sc->msi_count)) != 0) ||
380 1.1.2.2 uebayasi (sc->msi_count != msi_needed)) {
381 1.1.2.2 uebayasi device_printf(dev, "msix allocation failed - msi_count = %d"
382 1.1.2.2 uebayasi " msi_needed=%d will try msi err=%d\n", sc->msi_count,
383 1.1.2.2 uebayasi msi_needed, error);
384 1.1.2.2 uebayasi sc->msi_count = 0;
385 1.1.2.2 uebayasi pci_release_msi(dev);
386 1.1.2.2 uebayasi bus_release_resource(dev, SYS_RES_MEMORY,
387 1.1.2.2 uebayasi sc->msix_regs_rid, sc->msix_regs_res);
388 1.1.2.2 uebayasi sc->msix_regs_res = NULL;
389 1.1.2.2 uebayasi } else {
390 1.1.2.2 uebayasi sc->flags |= USING_MSIX;
391 1.1.2.2 uebayasi sc->cxgb_intr = t3_intr_msix;
392 1.1.2.2 uebayasi }
393 1.1.2.2 uebayasi }
394 1.1.2.2 uebayasi
395 1.1.2.2 uebayasi if ((msi_allowed >= 1) && (sc->msi_count == 0)) {
396 1.1.2.2 uebayasi sc->msi_count = 1;
397 1.1.2.2 uebayasi if (pci_alloc_msi(dev, &sc->msi_count)) {
398 1.1.2.2 uebayasi device_printf(dev, "alloc msi failed - will try INTx\n");
399 1.1.2.2 uebayasi sc->msi_count = 0;
400 1.1.2.2 uebayasi pci_release_msi(dev);
401 1.1.2.2 uebayasi } else {
402 1.1.2.2 uebayasi sc->flags |= USING_MSI;
403 1.1.2.2 uebayasi sc->irq_rid = 1;
404 1.1.2.2 uebayasi sc->cxgb_intr = t3_intr_msi;
405 1.1.2.2 uebayasi }
406 1.1.2.2 uebayasi }
407 1.1.2.2 uebayasi #endif
408 1.1.2.2 uebayasi if (sc->msi_count == 0) {
409 1.1.2.2 uebayasi device_printf(dev, "using line interrupts\n");
410 1.1.2.2 uebayasi sc->irq_rid = 0;
411 1.1.2.2 uebayasi sc->cxgb_intr = t3b_intr;
412 1.1.2.2 uebayasi }
413 1.1.2.2 uebayasi
414 1.1.2.2 uebayasi sc->ext_intr_task.name = "cxgb_ext_intr_handler";
415 1.1.2.2 uebayasi sc->ext_intr_task.func = cxgb_ext_intr_handler;
416 1.1.2.2 uebayasi sc->ext_intr_task.context = sc;
417 1.1.2.2 uebayasi kthread_create(PRI_NONE, 0, NULL, cxgb_make_task, &sc->ext_intr_task, NULL, "cxgb_make_task");
418 1.1.2.2 uebayasi
419 1.1.2.2 uebayasi sc->tick_task.name = "cxgb_tick_handler";
420 1.1.2.2 uebayasi sc->tick_task.func = cxgb_tick_handler;
421 1.1.2.2 uebayasi sc->tick_task.context = sc;
422 1.1.2.2 uebayasi kthread_create(PRI_NONE, 0, NULL, cxgb_make_task, &sc->tick_task, NULL, "cxgb_make_task");
423 1.1.2.2 uebayasi
424 1.1.2.2 uebayasi /* Create a periodic callout for checking adapter status */
425 1.1.2.2 uebayasi callout_init(&sc->cxgb_tick_ch, 0);
426 1.1.2.2 uebayasi
427 1.1.2.2 uebayasi if (t3_check_fw_version(sc) != 0) {
428 1.1.2.2 uebayasi /*
429 1.1.2.2 uebayasi * Warn user that a firmware update will be attempted in init.
430 1.1.2.2 uebayasi */
431 1.1.2.2 uebayasi device_printf(dev, "firmware needs to be updated to version %d.%d.%d\n",
432 1.1.2.2 uebayasi FW_VERSION_MAJOR, FW_VERSION_MINOR, FW_VERSION_MICRO);
433 1.1.2.2 uebayasi sc->flags &= ~FW_UPTODATE;
434 1.1.2.2 uebayasi } else {
435 1.1.2.2 uebayasi sc->flags |= FW_UPTODATE;
436 1.1.2.2 uebayasi }
437 1.1.2.2 uebayasi
438 1.1.2.2 uebayasi if (t3_check_tpsram_version(sc) != 0) {
439 1.1.2.2 uebayasi /*
440 1.1.2.2 uebayasi * Warn user that a firmware update will be attempted in init.
441 1.1.2.2 uebayasi */
442 1.1.2.2 uebayasi device_printf(dev, "SRAM needs to be updated to version %c-%d.%d.%d\n",
443 1.1.2.2 uebayasi t3rev2char(sc), TP_VERSION_MAJOR, TP_VERSION_MINOR, TP_VERSION_MICRO);
444 1.1.2.2 uebayasi sc->flags &= ~TPS_UPTODATE;
445 1.1.2.2 uebayasi } else {
446 1.1.2.2 uebayasi sc->flags |= TPS_UPTODATE;
447 1.1.2.2 uebayasi }
448 1.1.2.2 uebayasi
449 1.1.2.2 uebayasi if ((sc->flags & USING_MSIX) && !singleq)
450 1.1.2.2 uebayasi port_qsets = (SGE_QSETS/(sc)->params.nports);
451 1.1.2.2 uebayasi
452 1.1.2.2 uebayasi /*
453 1.1.2.2 uebayasi * Create a child device for each MAC. The ethernet attachment
454 1.1.2.2 uebayasi * will be done in these children.
455 1.1.2.2 uebayasi */
456 1.1.2.2 uebayasi for (i = 0; i < (sc)->params.nports; i++) {
457 1.1.2.2 uebayasi struct port_info *pi;
458 1.1.2.2 uebayasi
459 1.1.2.2 uebayasi pi = &sc->port[i];
460 1.1.2.2 uebayasi pi->adapter = sc;
461 1.1.2.2 uebayasi pi->nqsets = port_qsets;
462 1.1.2.2 uebayasi pi->first_qset = i*port_qsets;
463 1.1.2.2 uebayasi pi->port_id = i;
464 1.1.2.2 uebayasi pi->tx_chan = i >= ai->nports0;
465 1.1.2.2 uebayasi pi->txpkt_intf = pi->tx_chan ? 2 * (i - ai->nports0) + 1 : 2 * i;
466 1.1.2.2 uebayasi sc->rxpkt_map[pi->txpkt_intf] = i;
467 1.1.2.2 uebayasi cxgb_args.port = i;
468 1.1.2.2 uebayasi locs[0] = 1;
469 1.1.2.2 uebayasi locs[1] = i;
470 1.1.2.2 uebayasi printf("\n"); // for cleaner formatting in dmesg
471 1.1.2.2 uebayasi child = config_found_sm_loc(dev, "cxgbc", locs, &cxgb_args,
472 1.1.2.2 uebayasi cxgb_cfprint, config_stdsubmatch);
473 1.1.2.2 uebayasi printf("\n"); // for cleaner formatting in dmesg
474 1.1.2.2 uebayasi sc->portdev[i] = child;
475 1.1.2.2 uebayasi }
476 1.1.2.2 uebayasi
477 1.1.2.2 uebayasi /*
478 1.1.2.2 uebayasi * XXX need to poll for link status
479 1.1.2.2 uebayasi */
480 1.1.2.2 uebayasi sc->params.stats_update_period = 1;
481 1.1.2.2 uebayasi
482 1.1.2.2 uebayasi /* initialize sge private state */
483 1.1.2.2 uebayasi t3_sge_init_adapter(sc);
484 1.1.2.2 uebayasi
485 1.1.2.2 uebayasi t3_led_ready(sc);
486 1.1.2.2 uebayasi
487 1.1.2.2 uebayasi error = t3_get_fw_version(sc, &vers);
488 1.1.2.2 uebayasi if (error)
489 1.1.2.2 uebayasi goto out;
490 1.1.2.2 uebayasi
491 1.1.2.2 uebayasi snprintf(&sc->fw_version[0], sizeof(sc->fw_version), "%d.%d.%d",
492 1.1.2.2 uebayasi G_FW_VERSION_MAJOR(vers), G_FW_VERSION_MINOR(vers),
493 1.1.2.2 uebayasi G_FW_VERSION_MICRO(vers));
494 1.1.2.2 uebayasi out:
495 1.1.2.2 uebayasi if (error)
496 1.1.2.2 uebayasi {
497 1.1.2.2 uebayasi cxgb_free(sc);
498 1.1.2.2 uebayasi }
499 1.1.2.2 uebayasi }
500 1.1.2.2 uebayasi
501 1.1.2.2 uebayasi static int
502 1.1.2.2 uebayasi cxgb_controller_detach(device_t dev, int flags)
503 1.1.2.2 uebayasi {
504 1.1.2.2 uebayasi struct adapter *sc;
505 1.1.2.2 uebayasi
506 1.1.2.2 uebayasi sc = device_private(dev);
507 1.1.2.2 uebayasi
508 1.1.2.2 uebayasi cxgb_free(sc);
509 1.1.2.2 uebayasi
510 1.1.2.2 uebayasi return (0);
511 1.1.2.2 uebayasi }
512 1.1.2.2 uebayasi
513 1.1.2.2 uebayasi static void
514 1.1.2.2 uebayasi cxgb_free(struct adapter *sc)
515 1.1.2.2 uebayasi {
516 1.1.2.2 uebayasi int i;
517 1.1.2.2 uebayasi
518 1.1.2.2 uebayasi ADAPTER_LOCK(sc);
519 1.1.2.2 uebayasi /*
520 1.1.2.2 uebayasi * drops the lock
521 1.1.2.2 uebayasi */
522 1.1.2.2 uebayasi cxgb_down_locked(sc);
523 1.1.2.2 uebayasi
524 1.1.2.2 uebayasi #ifdef MSI_SUPPORTED
525 1.1.2.2 uebayasi if (sc->flags & (USING_MSI | USING_MSIX)) {
526 1.1.2.2 uebayasi device_printf(sc->dev, "releasing msi message(s)\n");
527 1.1.2.2 uebayasi pci_release_msi(sc->dev);
528 1.1.2.2 uebayasi } else {
529 1.1.2.2 uebayasi device_printf(sc->dev, "no msi message to release\n");
530 1.1.2.2 uebayasi }
531 1.1.2.2 uebayasi if (sc->msix_regs_res != NULL) {
532 1.1.2.2 uebayasi bus_release_resource(sc->dev, SYS_RES_MEMORY, sc->msix_regs_rid,
533 1.1.2.2 uebayasi sc->msix_regs_res);
534 1.1.2.2 uebayasi }
535 1.1.2.2 uebayasi #endif
536 1.1.2.2 uebayasi
537 1.1.2.2 uebayasi t3_sge_deinit_sw(sc);
538 1.1.2.2 uebayasi /*
539 1.1.2.2 uebayasi * Wait for last callout
540 1.1.2.2 uebayasi */
541 1.1.2.2 uebayasi
542 1.1.2.2 uebayasi tsleep(&sc, 0, "cxgb unload", 3*hz);
543 1.1.2.2 uebayasi
544 1.1.2.2 uebayasi for (i = 0; i < (sc)->params.nports; ++i) {
545 1.1.2.2 uebayasi if (sc->portdev[i] != NULL)
546 1.1.2.2 uebayasi {
547 1.1.2.2 uebayasi INT3;
548 1.1.2.2 uebayasi }
549 1.1.2.2 uebayasi }
550 1.1.2.2 uebayasi
551 1.1.2.2 uebayasi #ifdef notyet
552 1.1.2.2 uebayasi if (is_offload(sc)) {
553 1.1.2.2 uebayasi cxgb_adapter_unofld(sc);
554 1.1.2.2 uebayasi if (isset(&sc->open_device_map, OFFLOAD_DEVMAP_BIT))
555 1.1.2.2 uebayasi offload_close(&sc->tdev);
556 1.1.2.2 uebayasi }
557 1.1.2.2 uebayasi #endif
558 1.1.2.2 uebayasi
559 1.1.2.2 uebayasi t3_free_sge_resources(sc);
560 1.1.2.2 uebayasi free(sc->filters, M_DEVBUF);
561 1.1.2.2 uebayasi t3_sge_free(sc);
562 1.1.2.2 uebayasi
563 1.1.2.2 uebayasi MTX_DESTROY(&sc->mdio_lock);
564 1.1.2.2 uebayasi MTX_DESTROY(&sc->sge.reg_lock);
565 1.1.2.2 uebayasi MTX_DESTROY(&sc->elmer_lock);
566 1.1.2.2 uebayasi ADAPTER_LOCK_DEINIT(sc);
567 1.1.2.2 uebayasi
568 1.1.2.2 uebayasi return;
569 1.1.2.2 uebayasi }
570 1.1.2.2 uebayasi
571 1.1.2.2 uebayasi /**
572 1.1.2.2 uebayasi * setup_sge_qsets - configure SGE Tx/Rx/response queues
573 1.1.2.2 uebayasi * @sc: the controller softc
574 1.1.2.2 uebayasi *
575 1.1.2.2 uebayasi * Determines how many sets of SGE queues to use and initializes them.
576 1.1.2.2 uebayasi * We support multiple queue sets per port if we have MSI-X, otherwise
577 1.1.2.2 uebayasi * just one queue set per port.
578 1.1.2.2 uebayasi */
579 1.1.2.2 uebayasi static int
580 1.1.2.2 uebayasi setup_sge_qsets(adapter_t *sc)
581 1.1.2.2 uebayasi {
582 1.1.2.2 uebayasi int i, j, err, irq_idx = 0, qset_idx = 0;
583 1.1.2.2 uebayasi u_int ntxq = SGE_TXQ_PER_SET;
584 1.1.2.2 uebayasi
585 1.1.2.2 uebayasi if ((err = t3_sge_alloc(sc)) != 0) {
586 1.1.2.2 uebayasi device_printf(sc->dev, "t3_sge_alloc returned %d\n", err);
587 1.1.2.2 uebayasi return (err);
588 1.1.2.2 uebayasi }
589 1.1.2.2 uebayasi
590 1.1.2.2 uebayasi if (sc->params.rev > 0 && !(sc->flags & USING_MSI))
591 1.1.2.2 uebayasi irq_idx = -1;
592 1.1.2.2 uebayasi
593 1.1.2.2 uebayasi for (i = 0; i < (sc)->params.nports; i++) {
594 1.1.2.2 uebayasi struct port_info *pi = &sc->port[i];
595 1.1.2.2 uebayasi
596 1.1.2.2 uebayasi for (j = 0; j < pi->nqsets; j++, qset_idx++) {
597 1.1.2.2 uebayasi err = t3_sge_alloc_qset(sc, qset_idx, (sc)->params.nports,
598 1.1.2.2 uebayasi (sc->flags & USING_MSIX) ? qset_idx + 1 : irq_idx,
599 1.1.2.2 uebayasi &sc->params.sge.qset[qset_idx], ntxq, pi);
600 1.1.2.2 uebayasi if (err) {
601 1.1.2.2 uebayasi t3_free_sge_resources(sc);
602 1.1.2.2 uebayasi device_printf(sc->dev, "t3_sge_alloc_qset failed with %d\n",
603 1.1.2.2 uebayasi err);
604 1.1.2.2 uebayasi return (err);
605 1.1.2.2 uebayasi }
606 1.1.2.2 uebayasi }
607 1.1.2.2 uebayasi }
608 1.1.2.2 uebayasi
609 1.1.2.2 uebayasi return (0);
610 1.1.2.2 uebayasi }
611 1.1.2.2 uebayasi
612 1.1.2.2 uebayasi static void
613 1.1.2.2 uebayasi cxgb_teardown_msix(adapter_t *sc)
614 1.1.2.2 uebayasi {
615 1.1.2.2 uebayasi int i, nqsets;
616 1.1.2.2 uebayasi
617 1.1.2.2 uebayasi for (nqsets = i = 0; i < (sc)->params.nports; i++)
618 1.1.2.2 uebayasi nqsets += sc->port[i].nqsets;
619 1.1.2.2 uebayasi
620 1.1.2.2 uebayasi for (i = 0; i < nqsets; i++) {
621 1.1.2.2 uebayasi if (sc->msix_intr_tag[i] != NULL) {
622 1.1.2.2 uebayasi sc->msix_intr_tag[i] = NULL;
623 1.1.2.2 uebayasi }
624 1.1.2.2 uebayasi if (sc->msix_irq_res[i] != NULL) {
625 1.1.2.2 uebayasi sc->msix_irq_res[i] = NULL;
626 1.1.2.2 uebayasi }
627 1.1.2.2 uebayasi }
628 1.1.2.2 uebayasi }
629 1.1.2.2 uebayasi
630 1.1.2.2 uebayasi static int
631 1.1.2.2 uebayasi cxgb_setup_msix(adapter_t *sc, int msix_count)
632 1.1.2.2 uebayasi {
633 1.1.2.2 uebayasi int i, j, k, nqsets, rid;
634 1.1.2.2 uebayasi
635 1.1.2.2 uebayasi /* The first message indicates link changes and error conditions */
636 1.1.2.2 uebayasi sc->irq_rid = 1;
637 1.1.2.2 uebayasi /* Allocate PCI interrupt resources. */
638 1.1.2.2 uebayasi if (pci_intr_map(&sc->pa, &sc->intr_handle))
639 1.1.2.2 uebayasi {
640 1.1.2.2 uebayasi printf("cxgb_setup_msix(%d): pci_intr_map() failed\n", __LINE__);
641 1.1.2.2 uebayasi return (EINVAL);
642 1.1.2.2 uebayasi }
643 1.1.2.2 uebayasi sc->intr_cookie = pci_intr_establish(sc->pa.pa_pc, sc->intr_handle,
644 1.1.2.2 uebayasi IPL_NET, cxgb_async_intr, sc);
645 1.1.2.2 uebayasi if (sc->intr_cookie == NULL)
646 1.1.2.2 uebayasi {
647 1.1.2.2 uebayasi printf("cxgb_setup_msix(%d): pci_intr_establish() failed\n", __LINE__);
648 1.1.2.2 uebayasi return (EINVAL);
649 1.1.2.2 uebayasi }
650 1.1.2.2 uebayasi for (i = k = 0; i < (sc)->params.nports; i++) {
651 1.1.2.2 uebayasi nqsets = sc->port[i].nqsets;
652 1.1.2.2 uebayasi for (j = 0; j < nqsets; j++, k++) {
653 1.1.2.2 uebayasi rid = k + 2;
654 1.1.2.2 uebayasi if (cxgb_debug)
655 1.1.2.2 uebayasi printf("rid=%d ", rid);
656 1.1.2.2 uebayasi INT3;
657 1.1.2.2 uebayasi }
658 1.1.2.2 uebayasi }
659 1.1.2.2 uebayasi
660 1.1.2.2 uebayasi
661 1.1.2.2 uebayasi return (0);
662 1.1.2.2 uebayasi }
663 1.1.2.2 uebayasi
664 1.1.2.2 uebayasi static int cxgb_port_match(device_t dev, cfdata_t match, void *context)
665 1.1.2.2 uebayasi {
666 1.1.2.2 uebayasi return (100);
667 1.1.2.2 uebayasi }
668 1.1.2.2 uebayasi
669 1.1.2.2 uebayasi #define IFCAP_HWCSUM (IFCAP_CSUM_IPv4_Rx | IFCAP_CSUM_IPv4_Tx)
670 1.1.2.2 uebayasi #define IFCAP_RXCSUM IFCAP_CSUM_IPv4_Rx
671 1.1.2.2 uebayasi #define IFCAP_TXCSUM IFCAP_CSUM_IPv4_Tx
672 1.1.2.2 uebayasi
673 1.1.2.2 uebayasi #ifdef TSO_SUPPORTED
674 1.1.2.2 uebayasi #define CXGB_CAP (IFCAP_HWCSUM | IFCAP_TSO)
675 1.1.2.2 uebayasi /* Don't enable TSO6 yet */
676 1.1.2.2 uebayasi #define CXGB_CAP_ENABLE (IFCAP_HWCSUM | IFCAP_TSO4)
677 1.1.2.2 uebayasi #else
678 1.1.2.2 uebayasi #define CXGB_CAP (IFCAP_HWCSUM)
679 1.1.2.2 uebayasi /* Don't enable TSO6 yet */
680 1.1.2.2 uebayasi #define CXGB_CAP_ENABLE (IFCAP_HWCSUM)
681 1.1.2.2 uebayasi #define IFCAP_TSO4 0x0
682 1.1.2.2 uebayasi #define IFCAP_TSO6 0x0
683 1.1.2.2 uebayasi #define CSUM_TSO 0x0
684 1.1.2.2 uebayasi #endif
685 1.1.2.2 uebayasi
686 1.1.2.2 uebayasi static void
687 1.1.2.2 uebayasi cxgb_port_attach(device_t dev, device_t self, void *context)
688 1.1.2.2 uebayasi {
689 1.1.2.2 uebayasi struct port_info *p;
690 1.1.2.2 uebayasi struct port_device *pd;
691 1.1.2.2 uebayasi int *port_number = (int *)context;
692 1.1.2.2 uebayasi char buf[32];
693 1.1.2.2 uebayasi struct ifnet *ifp;
694 1.1.2.2 uebayasi int media_flags;
695 1.1.2.2 uebayasi pd = (struct port_device *)self; // device is first element in port_device
696 1.1.2.2 uebayasi pd->dev = self;
697 1.1.2.2 uebayasi pd->parent = (struct adapter *)dev;
698 1.1.2.2 uebayasi pd->port_number = *port_number;
699 1.1.2.2 uebayasi p = &pd->parent->port[*port_number];
700 1.1.2.2 uebayasi p->pd = pd;
701 1.1.2.2 uebayasi
702 1.1.2.2 uebayasi PORT_LOCK_INIT(p, p->lockbuf);
703 1.1.2.2 uebayasi
704 1.1.2.2 uebayasi /* Allocate an ifnet object and set it up */
705 1.1.2.2 uebayasi ifp = p->ifp = (void *)malloc(sizeof (struct ifnet), M_IFADDR, M_WAITOK);
706 1.1.2.2 uebayasi if (ifp == NULL) {
707 1.1.2.2 uebayasi device_printf(dev, "Cannot allocate ifnet\n");
708 1.1.2.2 uebayasi return;
709 1.1.2.2 uebayasi }
710 1.1.2.2 uebayasi memset(ifp, 0, sizeof(struct ifnet));
711 1.1.2.2 uebayasi
712 1.1.2.2 uebayasi /*
713 1.1.2.2 uebayasi * Note that there is currently no watchdog timer.
714 1.1.2.2 uebayasi */
715 1.1.2.2 uebayasi snprintf(buf, sizeof(buf), "cxgb%d", p->port);
716 1.1.2.2 uebayasi strcpy(ifp->if_xname, buf);
717 1.1.2.2 uebayasi ifp->if_init = cxgb_init;
718 1.1.2.2 uebayasi ifp->if_softc = p;
719 1.1.2.2 uebayasi ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
720 1.1.2.2 uebayasi ifp->if_ioctl = cxgb_ioctl;
721 1.1.2.2 uebayasi ifp->if_start = cxgb_start;
722 1.1.2.2 uebayasi ifp->if_stop = cxgb_stop;
723 1.1.2.2 uebayasi ifp->if_timer = 0; /* Disable ifnet watchdog */
724 1.1.2.2 uebayasi ifp->if_watchdog = NULL;
725 1.1.2.2 uebayasi
726 1.1.2.2 uebayasi ifp->if_snd.ifq_maxlen = TX_ETH_Q_SIZE;
727 1.1.2.2 uebayasi IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_maxlen);
728 1.1.2.2 uebayasi
729 1.1.2.2 uebayasi IFQ_SET_READY(&ifp->if_snd);
730 1.1.2.2 uebayasi
731 1.1.2.2 uebayasi ifp->if_capabilities = ifp->if_capenable = 0;
732 1.1.2.2 uebayasi ifp->if_baudrate = 10000000000; // 10 Gbps
733 1.1.2.2 uebayasi /*
734 1.1.2.2 uebayasi * disable TSO on 4-port - it isn't supported by the firmware yet
735 1.1.2.2 uebayasi */
736 1.1.2.2 uebayasi if (p->adapter->params.nports > 2) {
737 1.1.2.2 uebayasi ifp->if_capabilities &= ~(IFCAP_TSO4 | IFCAP_TSO6);
738 1.1.2.2 uebayasi ifp->if_capenable &= ~(IFCAP_TSO4 | IFCAP_TSO6);
739 1.1.2.2 uebayasi }
740 1.1.2.2 uebayasi
741 1.1.2.2 uebayasi if_attach(ifp);
742 1.1.2.2 uebayasi ether_ifattach(ifp, p->hw_addr);
743 1.1.2.2 uebayasi /*
744 1.1.2.2 uebayasi * Only default to jumbo frames on 10GigE
745 1.1.2.2 uebayasi */
746 1.1.2.2 uebayasi if (p->adapter->params.nports <= 2)
747 1.1.2.2 uebayasi ifp->if_mtu = 9000;
748 1.1.2.2 uebayasi ifmedia_init(&p->media, IFM_IMASK, cxgb_media_change,
749 1.1.2.2 uebayasi cxgb_media_status);
750 1.1.2.2 uebayasi
751 1.1.2.2 uebayasi if (!strcmp(p->port_type->desc, "10GBASE-CX4")) {
752 1.1.2.2 uebayasi media_flags = IFM_ETHER | IFM_10G_CX4 | IFM_FDX;
753 1.1.2.2 uebayasi } else if (!strcmp(p->port_type->desc, "10GBASE-SR")) {
754 1.1.2.2 uebayasi media_flags = IFM_ETHER | IFM_10G_SR | IFM_FDX;
755 1.1.2.2 uebayasi } else if (!strcmp(p->port_type->desc, "10GBASE-XR")) {
756 1.1.2.2 uebayasi media_flags = IFM_ETHER | IFM_10G_LR | IFM_FDX;
757 1.1.2.2 uebayasi } else if (!strcmp(p->port_type->desc, "10/100/1000BASE-T")) {
758 1.1.2.2 uebayasi ifmedia_add(&p->media, IFM_ETHER | IFM_10_T, 0, NULL);
759 1.1.2.2 uebayasi ifmedia_add(&p->media, IFM_ETHER | IFM_10_T | IFM_FDX,
760 1.1.2.2 uebayasi 0, NULL);
761 1.1.2.2 uebayasi ifmedia_add(&p->media, IFM_ETHER | IFM_100_TX,
762 1.1.2.2 uebayasi 0, NULL);
763 1.1.2.2 uebayasi ifmedia_add(&p->media, IFM_ETHER | IFM_100_TX | IFM_FDX,
764 1.1.2.2 uebayasi 0, NULL);
765 1.1.2.2 uebayasi ifmedia_add(&p->media, IFM_ETHER | IFM_1000_T | IFM_FDX,
766 1.1.2.2 uebayasi 0, NULL);
767 1.1.2.2 uebayasi media_flags = 0;
768 1.1.2.2 uebayasi } else {
769 1.1.2.2 uebayasi printf("unsupported media type %s\n", p->port_type->desc);
770 1.1.2.2 uebayasi return;
771 1.1.2.2 uebayasi }
772 1.1.2.2 uebayasi if (media_flags) {
773 1.1.2.2 uebayasi ifmedia_add(&p->media, media_flags, 0, NULL);
774 1.1.2.2 uebayasi ifmedia_set(&p->media, media_flags);
775 1.1.2.2 uebayasi } else {
776 1.1.2.2 uebayasi ifmedia_add(&p->media, IFM_ETHER | IFM_AUTO, 0, NULL);
777 1.1.2.2 uebayasi ifmedia_set(&p->media, IFM_ETHER | IFM_AUTO);
778 1.1.2.2 uebayasi }
779 1.1.2.2 uebayasi
780 1.1.2.2 uebayasi snprintf(p->taskqbuf, TASKQ_NAME_LEN, "cxgb_port_taskq%d", p->port_id);
781 1.1.2.2 uebayasi p->start_task.name = "cxgb_start_proc";
782 1.1.2.2 uebayasi p->start_task.func = cxgb_start_proc;
783 1.1.2.2 uebayasi p->start_task.context = ifp;
784 1.1.2.2 uebayasi kthread_create(PRI_NONE, 0, NULL, cxgb_make_task, &p->start_task, NULL, "cxgb_make_task");
785 1.1.2.2 uebayasi
786 1.1.2.2 uebayasi t3_sge_init_port(p);
787 1.1.2.2 uebayasi }
788 1.1.2.2 uebayasi
789 1.1.2.2 uebayasi static int
790 1.1.2.2 uebayasi cxgb_port_detach(device_t dev, int flags)
791 1.1.2.2 uebayasi {
792 1.1.2.2 uebayasi struct port_info *p;
793 1.1.2.2 uebayasi
794 1.1.2.2 uebayasi p = (struct port_info *)dev; // device is first thing in adapter
795 1.1.2.2 uebayasi
796 1.1.2.2 uebayasi PORT_LOCK(p);
797 1.1.2.2 uebayasi if (p->ifp->if_drv_flags & IFF_DRV_RUNNING)
798 1.1.2.2 uebayasi cxgb_stop_locked(p);
799 1.1.2.2 uebayasi PORT_UNLOCK(p);
800 1.1.2.2 uebayasi
801 1.1.2.2 uebayasi if (p->start_task.wq != NULL) {
802 1.1.2.2 uebayasi workqueue_destroy(p->start_task.wq);
803 1.1.2.2 uebayasi p->start_task.wq = NULL;
804 1.1.2.2 uebayasi }
805 1.1.2.2 uebayasi
806 1.1.2.2 uebayasi ether_ifdetach(p->ifp);
807 1.1.2.2 uebayasi /*
808 1.1.2.2 uebayasi * the lock may be acquired in ifdetach
809 1.1.2.2 uebayasi */
810 1.1.2.2 uebayasi PORT_LOCK_DEINIT(p);
811 1.1.2.2 uebayasi if_detach(p->ifp);
812 1.1.2.2 uebayasi
813 1.1.2.2 uebayasi return (0);
814 1.1.2.2 uebayasi }
815 1.1.2.2 uebayasi
816 1.1.2.2 uebayasi void
817 1.1.2.2 uebayasi t3_fatal_err(struct adapter *sc)
818 1.1.2.2 uebayasi {
819 1.1.2.2 uebayasi u_int fw_status[4];
820 1.1.2.2 uebayasi
821 1.1.2.2 uebayasi if (sc->flags & FULL_INIT_DONE) {
822 1.1.2.2 uebayasi t3_sge_stop(sc);
823 1.1.2.2 uebayasi t3_write_reg(sc, A_XGM_TX_CTRL, 0);
824 1.1.2.2 uebayasi t3_write_reg(sc, A_XGM_RX_CTRL, 0);
825 1.1.2.2 uebayasi t3_write_reg(sc, XGM_REG(A_XGM_TX_CTRL, 1), 0);
826 1.1.2.2 uebayasi t3_write_reg(sc, XGM_REG(A_XGM_RX_CTRL, 1), 0);
827 1.1.2.2 uebayasi t3_intr_disable(sc);
828 1.1.2.2 uebayasi }
829 1.1.2.2 uebayasi device_printf(sc->dev,"encountered fatal error, operation suspended\n");
830 1.1.2.2 uebayasi if (!t3_cim_ctl_blk_read(sc, 0xa0, 4, fw_status))
831 1.1.2.2 uebayasi device_printf(sc->dev, "FW_ status: 0x%x, 0x%x, 0x%x, 0x%x\n",
832 1.1.2.2 uebayasi fw_status[0], fw_status[1], fw_status[2], fw_status[3]);
833 1.1.2.2 uebayasi }
834 1.1.2.2 uebayasi
835 1.1.2.2 uebayasi int
836 1.1.2.2 uebayasi t3_os_find_pci_capability(adapter_t *sc, int cap)
837 1.1.2.2 uebayasi {
838 1.1.2.2 uebayasi device_t dev;
839 1.1.2.2 uebayasi uint32_t status;
840 1.1.2.2 uebayasi uint32_t bhlc;
841 1.1.2.2 uebayasi uint32_t temp;
842 1.1.2.2 uebayasi uint8_t ptr;
843 1.1.2.2 uebayasi dev = sc->dev;
844 1.1.2.2 uebayasi status = pci_conf_read(sc->pa.pa_pc, sc->pa.pa_tag, PCI_COMMAND_STATUS_REG);
845 1.1.2.2 uebayasi if (!(status&PCI_STATUS_CAPLIST_SUPPORT))
846 1.1.2.2 uebayasi return (0);
847 1.1.2.2 uebayasi bhlc = pci_conf_read(sc->pa.pa_pc, sc->pa.pa_tag, PCI_BHLC_REG);
848 1.1.2.2 uebayasi switch (PCI_HDRTYPE(bhlc))
849 1.1.2.2 uebayasi {
850 1.1.2.2 uebayasi case 0:
851 1.1.2.2 uebayasi case 1:
852 1.1.2.2 uebayasi ptr = PCI_CAPLISTPTR_REG;
853 1.1.2.2 uebayasi break;
854 1.1.2.2 uebayasi case 2:
855 1.1.2.2 uebayasi ptr = PCI_CARDBUS_CAPLISTPTR_REG;
856 1.1.2.2 uebayasi break;
857 1.1.2.2 uebayasi default:
858 1.1.2.2 uebayasi return (0);
859 1.1.2.2 uebayasi }
860 1.1.2.2 uebayasi temp = pci_conf_read(sc->pa.pa_pc, sc->pa.pa_tag, ptr);
861 1.1.2.2 uebayasi ptr = PCI_CAPLIST_PTR(temp);
862 1.1.2.2 uebayasi while (ptr != 0) {
863 1.1.2.2 uebayasi temp = pci_conf_read(sc->pa.pa_pc, sc->pa.pa_tag, ptr);
864 1.1.2.2 uebayasi if (PCI_CAPLIST_CAP(temp) == cap)
865 1.1.2.2 uebayasi return (ptr);
866 1.1.2.2 uebayasi ptr = PCI_CAPLIST_NEXT(temp);
867 1.1.2.2 uebayasi }
868 1.1.2.2 uebayasi
869 1.1.2.2 uebayasi return (0);
870 1.1.2.2 uebayasi }
871 1.1.2.2 uebayasi
872 1.1.2.2 uebayasi int
873 1.1.2.2 uebayasi t3_os_pci_save_state(struct adapter *sc)
874 1.1.2.2 uebayasi {
875 1.1.2.2 uebayasi INT3;
876 1.1.2.2 uebayasi return (0);
877 1.1.2.2 uebayasi }
878 1.1.2.2 uebayasi
879 1.1.2.2 uebayasi int
880 1.1.2.2 uebayasi t3_os_pci_restore_state(struct adapter *sc)
881 1.1.2.2 uebayasi {
882 1.1.2.2 uebayasi INT3;
883 1.1.2.2 uebayasi return (0);
884 1.1.2.2 uebayasi }
885 1.1.2.2 uebayasi
886 1.1.2.2 uebayasi /**
887 1.1.2.2 uebayasi * t3_os_link_changed - handle link status changes
888 1.1.2.2 uebayasi * @adapter: the adapter associated with the link change
889 1.1.2.2 uebayasi * @port_id: the port index whose limk status has changed
890 1.1.2.2 uebayasi * @link_stat: the new status of the link
891 1.1.2.2 uebayasi * @speed: the new speed setting
892 1.1.2.2 uebayasi * @duplex: the new duplex setting
893 1.1.2.2 uebayasi * @fc: the new flow-control setting
894 1.1.2.2 uebayasi *
895 1.1.2.2 uebayasi * This is the OS-dependent handler for link status changes. The OS
896 1.1.2.2 uebayasi * neutral handler takes care of most of the processing for these events,
897 1.1.2.2 uebayasi * then calls this handler for any OS-specific processing.
898 1.1.2.2 uebayasi */
899 1.1.2.2 uebayasi void
900 1.1.2.2 uebayasi t3_os_link_changed(adapter_t *adapter, int port_id, int link_status, int speed,
901 1.1.2.2 uebayasi int duplex, int fc)
902 1.1.2.2 uebayasi {
903 1.1.2.2 uebayasi struct port_info *pi = &adapter->port[port_id];
904 1.1.2.2 uebayasi struct cmac *mac = &adapter->port[port_id].mac;
905 1.1.2.2 uebayasi
906 1.1.2.2 uebayasi if ((pi->ifp->if_flags & IFF_UP) == 0)
907 1.1.2.2 uebayasi return;
908 1.1.2.2 uebayasi
909 1.1.2.2 uebayasi if (link_status) {
910 1.1.2.2 uebayasi t3_mac_enable(mac, MAC_DIRECTION_RX);
911 1.1.2.2 uebayasi if_link_state_change(pi->ifp, LINK_STATE_UP);
912 1.1.2.2 uebayasi } else {
913 1.1.2.2 uebayasi if_link_state_change(pi->ifp, LINK_STATE_DOWN);
914 1.1.2.2 uebayasi pi->phy.ops->power_down(&pi->phy, 1);
915 1.1.2.2 uebayasi t3_mac_disable(mac, MAC_DIRECTION_RX);
916 1.1.2.2 uebayasi t3_link_start(&pi->phy, mac, &pi->link_config);
917 1.1.2.2 uebayasi }
918 1.1.2.2 uebayasi }
919 1.1.2.2 uebayasi
920 1.1.2.2 uebayasi /*
921 1.1.2.2 uebayasi * Interrupt-context handler for external (PHY) interrupts.
922 1.1.2.2 uebayasi */
923 1.1.2.2 uebayasi void
924 1.1.2.2 uebayasi t3_os_ext_intr_handler(adapter_t *sc)
925 1.1.2.2 uebayasi {
926 1.1.2.2 uebayasi if (cxgb_debug)
927 1.1.2.2 uebayasi printf("t3_os_ext_intr_handler\n");
928 1.1.2.2 uebayasi /*
929 1.1.2.2 uebayasi * Schedule a task to handle external interrupts as they may be slow
930 1.1.2.2 uebayasi * and we use a mutex to protect MDIO registers. We disable PHY
931 1.1.2.2 uebayasi * interrupts in the meantime and let the task reenable them when
932 1.1.2.2 uebayasi * it's done.
933 1.1.2.2 uebayasi */
934 1.1.2.2 uebayasi ADAPTER_LOCK(sc);
935 1.1.2.2 uebayasi if (sc->slow_intr_mask) {
936 1.1.2.2 uebayasi sc->slow_intr_mask &= ~F_T3DBG;
937 1.1.2.2 uebayasi t3_write_reg(sc, A_PL_INT_ENABLE0, sc->slow_intr_mask);
938 1.1.2.2 uebayasi workqueue_enqueue(sc->ext_intr_task.wq, &sc->ext_intr_task.w, NULL);
939 1.1.2.2 uebayasi }
940 1.1.2.2 uebayasi ADAPTER_UNLOCK(sc);
941 1.1.2.2 uebayasi }
942 1.1.2.2 uebayasi
943 1.1.2.2 uebayasi void
944 1.1.2.2 uebayasi t3_os_set_hw_addr(adapter_t *adapter, int port_idx, u8 hw_addr[])
945 1.1.2.2 uebayasi {
946 1.1.2.2 uebayasi
947 1.1.2.2 uebayasi /*
948 1.1.2.2 uebayasi * The ifnet might not be allocated before this gets called,
949 1.1.2.2 uebayasi * as this is called early on in attach by t3_prep_adapter
950 1.1.2.2 uebayasi * save the address off in the port structure
951 1.1.2.2 uebayasi */
952 1.1.2.2 uebayasi if (cxgb_debug)
953 1.1.2.2 uebayasi printf("set_hw_addr on idx %d addr %02x:%02x:%02x:%02x:%02x:%02x\n",
954 1.1.2.2 uebayasi port_idx, hw_addr[0], hw_addr[1], hw_addr[2], hw_addr[3], hw_addr[4], hw_addr[5]);
955 1.1.2.2 uebayasi memcpy(adapter->port[port_idx].hw_addr, hw_addr, ETHER_ADDR_LEN);
956 1.1.2.2 uebayasi }
957 1.1.2.2 uebayasi
958 1.1.2.2 uebayasi /**
959 1.1.2.2 uebayasi * link_start - enable a port
960 1.1.2.2 uebayasi * @p: the port to enable
961 1.1.2.2 uebayasi *
962 1.1.2.2 uebayasi * Performs the MAC and PHY actions needed to enable a port.
963 1.1.2.2 uebayasi */
964 1.1.2.2 uebayasi static void
965 1.1.2.2 uebayasi cxgb_link_start(struct port_info *p)
966 1.1.2.2 uebayasi {
967 1.1.2.2 uebayasi struct ifnet *ifp;
968 1.1.2.2 uebayasi struct t3_rx_mode rm;
969 1.1.2.2 uebayasi struct cmac *mac = &p->mac;
970 1.1.2.2 uebayasi
971 1.1.2.2 uebayasi ifp = p->ifp;
972 1.1.2.2 uebayasi
973 1.1.2.2 uebayasi t3_init_rx_mode(&rm, p);
974 1.1.2.2 uebayasi if (!mac->multiport)
975 1.1.2.2 uebayasi t3_mac_reset(mac);
976 1.1.2.2 uebayasi t3_mac_set_mtu(mac, ifp->if_mtu + ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN);
977 1.1.2.2 uebayasi t3_mac_set_address(mac, 0, p->hw_addr);
978 1.1.2.2 uebayasi t3_mac_set_rx_mode(mac, &rm);
979 1.1.2.2 uebayasi t3_link_start(&p->phy, mac, &p->link_config);
980 1.1.2.2 uebayasi t3_mac_enable(mac, MAC_DIRECTION_RX | MAC_DIRECTION_TX);
981 1.1.2.2 uebayasi }
982 1.1.2.2 uebayasi
983 1.1.2.2 uebayasi /**
984 1.1.2.2 uebayasi * setup_rss - configure Receive Side Steering (per-queue connection demux)
985 1.1.2.2 uebayasi * @adap: the adapter
986 1.1.2.2 uebayasi *
987 1.1.2.2 uebayasi * Sets up RSS to distribute packets to multiple receive queues. We
988 1.1.2.2 uebayasi * configure the RSS CPU lookup table to distribute to the number of HW
989 1.1.2.2 uebayasi * receive queues, and the response queue lookup table to narrow that
990 1.1.2.2 uebayasi * down to the response queues actually configured for each port.
991 1.1.2.2 uebayasi * We always configure the RSS mapping for two ports since the mapping
992 1.1.2.2 uebayasi * table has plenty of entries.
993 1.1.2.2 uebayasi */
994 1.1.2.2 uebayasi static void
995 1.1.2.2 uebayasi setup_rss(adapter_t *adap)
996 1.1.2.2 uebayasi {
997 1.1.2.2 uebayasi int i;
998 1.1.2.2 uebayasi u_int nq[2];
999 1.1.2.2 uebayasi uint8_t cpus[SGE_QSETS + 1];
1000 1.1.2.2 uebayasi uint16_t rspq_map[RSS_TABLE_SIZE];
1001 1.1.2.2 uebayasi
1002 1.1.2.2 uebayasi for (i = 0; i < SGE_QSETS; ++i)
1003 1.1.2.2 uebayasi cpus[i] = i;
1004 1.1.2.2 uebayasi cpus[SGE_QSETS] = 0xff;
1005 1.1.2.2 uebayasi
1006 1.1.2.2 uebayasi nq[0] = nq[1] = 0;
1007 1.1.2.2 uebayasi for_each_port(adap, i) {
1008 1.1.2.2 uebayasi const struct port_info *pi = adap2pinfo(adap, i);
1009 1.1.2.2 uebayasi
1010 1.1.2.2 uebayasi nq[pi->tx_chan] += pi->nqsets;
1011 1.1.2.2 uebayasi }
1012 1.1.2.2 uebayasi nq[0] = max(nq[0], 1U);
1013 1.1.2.2 uebayasi nq[1] = max(nq[1], 1U);
1014 1.1.2.2 uebayasi for (i = 0; i < RSS_TABLE_SIZE / 2; ++i) {
1015 1.1.2.2 uebayasi rspq_map[i] = i % nq[0];
1016 1.1.2.2 uebayasi rspq_map[i + RSS_TABLE_SIZE / 2] = (i % nq[1]) + nq[0];
1017 1.1.2.2 uebayasi }
1018 1.1.2.2 uebayasi /* Calculate the reverse RSS map table */
1019 1.1.2.2 uebayasi for (i = 0; i < RSS_TABLE_SIZE; ++i)
1020 1.1.2.2 uebayasi if (adap->rrss_map[rspq_map[i]] == 0xff)
1021 1.1.2.2 uebayasi adap->rrss_map[rspq_map[i]] = i;
1022 1.1.2.2 uebayasi
1023 1.1.2.2 uebayasi t3_config_rss(adap, F_RQFEEDBACKENABLE | F_TNLLKPEN | F_TNLMAPEN |
1024 1.1.2.2 uebayasi F_TNLPRTEN | F_TNL2TUPEN | F_TNL4TUPEN | F_OFDMAPEN |
1025 1.1.2.2 uebayasi V_RRCPLCPUSIZE(6), cpus, rspq_map);
1026 1.1.2.2 uebayasi
1027 1.1.2.2 uebayasi }
1028 1.1.2.2 uebayasi
1029 1.1.2.2 uebayasi /*
1030 1.1.2.2 uebayasi * Sends an mbuf to an offload queue driver
1031 1.1.2.2 uebayasi * after dealing with any active network taps.
1032 1.1.2.2 uebayasi */
1033 1.1.2.2 uebayasi static inline int
1034 1.1.2.2 uebayasi offload_tx(struct toedev *tdev, struct mbuf *m)
1035 1.1.2.2 uebayasi {
1036 1.1.2.2 uebayasi int ret;
1037 1.1.2.2 uebayasi
1038 1.1.2.2 uebayasi critical_enter();
1039 1.1.2.2 uebayasi ret = t3_offload_tx(tdev, m);
1040 1.1.2.2 uebayasi critical_exit();
1041 1.1.2.2 uebayasi return (ret);
1042 1.1.2.2 uebayasi }
1043 1.1.2.2 uebayasi
1044 1.1.2.2 uebayasi static void
1045 1.1.2.2 uebayasi send_pktsched_cmd(struct adapter *adap, int sched, int qidx, int lo,
1046 1.1.2.2 uebayasi int hi, int port)
1047 1.1.2.2 uebayasi {
1048 1.1.2.2 uebayasi struct mbuf *m;
1049 1.1.2.2 uebayasi struct mngt_pktsched_wr *req;
1050 1.1.2.2 uebayasi
1051 1.1.2.2 uebayasi m = m_gethdr(M_DONTWAIT, MT_DATA);
1052 1.1.2.2 uebayasi if (m) {
1053 1.1.2.2 uebayasi req = mtod(m, struct mngt_pktsched_wr *);
1054 1.1.2.2 uebayasi req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_MNGT));
1055 1.1.2.2 uebayasi req->mngt_opcode = FW_MNGTOPCODE_PKTSCHED_SET;
1056 1.1.2.2 uebayasi req->sched = sched;
1057 1.1.2.2 uebayasi req->idx = qidx;
1058 1.1.2.2 uebayasi req->min = lo;
1059 1.1.2.2 uebayasi req->max = hi;
1060 1.1.2.2 uebayasi req->binding = port;
1061 1.1.2.2 uebayasi m->m_len = m->m_pkthdr.len = sizeof(*req);
1062 1.1.2.2 uebayasi t3_mgmt_tx(adap, m);
1063 1.1.2.2 uebayasi }
1064 1.1.2.2 uebayasi }
1065 1.1.2.2 uebayasi
1066 1.1.2.2 uebayasi static void
1067 1.1.2.2 uebayasi bind_qsets(adapter_t *sc)
1068 1.1.2.2 uebayasi {
1069 1.1.2.2 uebayasi int i, j;
1070 1.1.2.2 uebayasi
1071 1.1.2.2 uebayasi for (i = 0; i < (sc)->params.nports; ++i) {
1072 1.1.2.2 uebayasi const struct port_info *pi = adap2pinfo(sc, i);
1073 1.1.2.2 uebayasi
1074 1.1.2.2 uebayasi for (j = 0; j < pi->nqsets; ++j) {
1075 1.1.2.2 uebayasi send_pktsched_cmd(sc, 1, pi->first_qset + j, -1,
1076 1.1.2.2 uebayasi -1, pi->tx_chan);
1077 1.1.2.2 uebayasi
1078 1.1.2.2 uebayasi }
1079 1.1.2.2 uebayasi }
1080 1.1.2.2 uebayasi }
1081 1.1.2.2 uebayasi
1082 1.1.2.2 uebayasi /**
1083 1.1.2.2 uebayasi * cxgb_up - enable the adapter
1084 1.1.2.2 uebayasi * @adap: adapter being enabled
1085 1.1.2.2 uebayasi *
1086 1.1.2.2 uebayasi * Called when the first port is enabled, this function performs the
1087 1.1.2.2 uebayasi * actions necessary to make an adapter operational, such as completing
1088 1.1.2.2 uebayasi * the initialization of HW modules, and enabling interrupts.
1089 1.1.2.2 uebayasi *
1090 1.1.2.2 uebayasi */
1091 1.1.2.2 uebayasi static int
1092 1.1.2.2 uebayasi cxgb_up(struct adapter *sc)
1093 1.1.2.2 uebayasi {
1094 1.1.2.2 uebayasi int err = 0;
1095 1.1.2.2 uebayasi
1096 1.1.2.2 uebayasi if ((sc->flags & FULL_INIT_DONE) == 0) {
1097 1.1.2.2 uebayasi
1098 1.1.2.2 uebayasi if ((sc->flags & FW_UPTODATE) == 0)
1099 1.1.2.2 uebayasi printf("SHOULD UPGRADE FIRMWARE!\n");
1100 1.1.2.2 uebayasi if ((sc->flags & TPS_UPTODATE) == 0)
1101 1.1.2.2 uebayasi printf("SHOULD UPDATE TPSRAM\n");
1102 1.1.2.2 uebayasi err = t3_init_hw(sc, 0);
1103 1.1.2.2 uebayasi if (err)
1104 1.1.2.2 uebayasi goto out;
1105 1.1.2.2 uebayasi
1106 1.1.2.2 uebayasi t3_write_reg(sc, A_ULPRX_TDDP_PSZ, V_HPZ0(PAGE_SHIFT - 12));
1107 1.1.2.2 uebayasi
1108 1.1.2.2 uebayasi err = setup_sge_qsets(sc);
1109 1.1.2.2 uebayasi if (err)
1110 1.1.2.2 uebayasi goto out;
1111 1.1.2.2 uebayasi
1112 1.1.2.2 uebayasi setup_rss(sc);
1113 1.1.2.2 uebayasi sc->flags |= FULL_INIT_DONE;
1114 1.1.2.2 uebayasi }
1115 1.1.2.2 uebayasi
1116 1.1.2.2 uebayasi t3_intr_clear(sc);
1117 1.1.2.2 uebayasi
1118 1.1.2.2 uebayasi /* If it's MSI or INTx, allocate a single interrupt for everything */
1119 1.1.2.2 uebayasi if ((sc->flags & USING_MSIX) == 0) {
1120 1.1.2.2 uebayasi if (pci_intr_map(&sc->pa, &sc->intr_handle))
1121 1.1.2.2 uebayasi {
1122 1.1.2.2 uebayasi device_printf(sc->dev, "Cannot allocate interrupt\n");
1123 1.1.2.2 uebayasi err = EINVAL;
1124 1.1.2.2 uebayasi goto out;
1125 1.1.2.2 uebayasi }
1126 1.1.2.2 uebayasi device_printf(sc->dev, "allocated intr_handle=%p\n", sc->intr_handle);
1127 1.1.2.2 uebayasi sc->intr_cookie = pci_intr_establish(sc->pa.pa_pc,
1128 1.1.2.2 uebayasi sc->intr_handle, IPL_NET,
1129 1.1.2.2 uebayasi sc->cxgb_intr, sc);
1130 1.1.2.2 uebayasi if (sc->intr_cookie == NULL)
1131 1.1.2.2 uebayasi {
1132 1.1.2.2 uebayasi device_printf(sc->dev, "Cannot establish interrupt\n");
1133 1.1.2.2 uebayasi err = EINVAL;
1134 1.1.2.2 uebayasi goto irq_err;
1135 1.1.2.2 uebayasi }
1136 1.1.2.2 uebayasi } else {
1137 1.1.2.2 uebayasi printf("Using MSIX?!?!?!\n");
1138 1.1.2.2 uebayasi INT3;
1139 1.1.2.2 uebayasi cxgb_setup_msix(sc, sc->msi_count);
1140 1.1.2.2 uebayasi }
1141 1.1.2.2 uebayasi
1142 1.1.2.2 uebayasi t3_sge_start(sc);
1143 1.1.2.2 uebayasi t3_intr_enable(sc);
1144 1.1.2.2 uebayasi
1145 1.1.2.2 uebayasi if (!(sc->flags & QUEUES_BOUND)) {
1146 1.1.2.2 uebayasi bind_qsets(sc);
1147 1.1.2.2 uebayasi sc->flags |= QUEUES_BOUND;
1148 1.1.2.2 uebayasi }
1149 1.1.2.2 uebayasi out:
1150 1.1.2.2 uebayasi return (err);
1151 1.1.2.2 uebayasi irq_err:
1152 1.1.2.2 uebayasi CH_ERR(sc, "request_irq failed, err %d\n", err);
1153 1.1.2.2 uebayasi goto out;
1154 1.1.2.2 uebayasi }
1155 1.1.2.2 uebayasi
1156 1.1.2.2 uebayasi
1157 1.1.2.2 uebayasi /*
1158 1.1.2.2 uebayasi * Release resources when all the ports and offloading have been stopped.
1159 1.1.2.2 uebayasi */
1160 1.1.2.2 uebayasi static void
1161 1.1.2.2 uebayasi cxgb_down_locked(struct adapter *sc)
1162 1.1.2.2 uebayasi {
1163 1.1.2.2 uebayasi t3_sge_stop(sc);
1164 1.1.2.2 uebayasi t3_intr_disable(sc);
1165 1.1.2.2 uebayasi
1166 1.1.2.2 uebayasi INT3; // XXXXXXXXXXXXXXXXXX
1167 1.1.2.2 uebayasi
1168 1.1.2.2 uebayasi if (sc->flags & USING_MSIX)
1169 1.1.2.2 uebayasi cxgb_teardown_msix(sc);
1170 1.1.2.2 uebayasi ADAPTER_UNLOCK(sc);
1171 1.1.2.2 uebayasi
1172 1.1.2.2 uebayasi callout_drain(&sc->cxgb_tick_ch);
1173 1.1.2.2 uebayasi callout_drain(&sc->sge_timer_ch);
1174 1.1.2.2 uebayasi
1175 1.1.2.2 uebayasi #ifdef notyet
1176 1.1.2.2 uebayasi
1177 1.1.2.2 uebayasi if (sc->port[i].tq != NULL)
1178 1.1.2.2 uebayasi #endif
1179 1.1.2.2 uebayasi
1180 1.1.2.2 uebayasi }
1181 1.1.2.2 uebayasi
1182 1.1.2.2 uebayasi static int
1183 1.1.2.2 uebayasi cxgb_init(struct ifnet *ifp)
1184 1.1.2.2 uebayasi {
1185 1.1.2.2 uebayasi struct port_info *p = ifp->if_softc;
1186 1.1.2.2 uebayasi
1187 1.1.2.2 uebayasi PORT_LOCK(p);
1188 1.1.2.2 uebayasi cxgb_init_locked(p);
1189 1.1.2.2 uebayasi PORT_UNLOCK(p);
1190 1.1.2.2 uebayasi
1191 1.1.2.2 uebayasi return (0); // ????????????
1192 1.1.2.2 uebayasi }
1193 1.1.2.2 uebayasi
1194 1.1.2.2 uebayasi static void
1195 1.1.2.2 uebayasi cxgb_init_locked(struct port_info *p)
1196 1.1.2.2 uebayasi {
1197 1.1.2.2 uebayasi struct ifnet *ifp;
1198 1.1.2.2 uebayasi adapter_t *sc = p->adapter;
1199 1.1.2.2 uebayasi int err;
1200 1.1.2.2 uebayasi
1201 1.1.2.2 uebayasi PORT_LOCK_ASSERT_OWNED(p);
1202 1.1.2.2 uebayasi ifp = p->ifp;
1203 1.1.2.2 uebayasi
1204 1.1.2.2 uebayasi ADAPTER_LOCK(p->adapter);
1205 1.1.2.2 uebayasi if ((sc->open_device_map == 0) && (err = cxgb_up(sc))) {
1206 1.1.2.2 uebayasi ADAPTER_UNLOCK(p->adapter);
1207 1.1.2.2 uebayasi cxgb_stop_locked(p);
1208 1.1.2.2 uebayasi return;
1209 1.1.2.2 uebayasi }
1210 1.1.2.2 uebayasi if (p->adapter->open_device_map == 0) {
1211 1.1.2.2 uebayasi t3_intr_clear(sc);
1212 1.1.2.2 uebayasi t3_sge_init_adapter(sc);
1213 1.1.2.2 uebayasi }
1214 1.1.2.2 uebayasi setbit(&p->adapter->open_device_map, p->port_id);
1215 1.1.2.2 uebayasi ADAPTER_UNLOCK(p->adapter);
1216 1.1.2.2 uebayasi
1217 1.1.2.2 uebayasi cxgb_link_start(p);
1218 1.1.2.2 uebayasi t3_link_changed(sc, p->port_id);
1219 1.1.2.2 uebayasi ifp->if_baudrate = p->link_config.speed * 1000000;
1220 1.1.2.2 uebayasi
1221 1.1.2.2 uebayasi device_printf(sc->dev, "enabling interrupts on port=%d\n", p->port_id);
1222 1.1.2.2 uebayasi t3_port_intr_enable(sc, p->port_id);
1223 1.1.2.2 uebayasi
1224 1.1.2.2 uebayasi callout_reset(&sc->cxgb_tick_ch, sc->params.stats_update_period * hz,
1225 1.1.2.2 uebayasi cxgb_tick, sc);
1226 1.1.2.2 uebayasi
1227 1.1.2.2 uebayasi ifp->if_drv_flags |= IFF_DRV_RUNNING;
1228 1.1.2.2 uebayasi ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
1229 1.1.2.2 uebayasi }
1230 1.1.2.2 uebayasi
1231 1.1.2.2 uebayasi static void
1232 1.1.2.2 uebayasi cxgb_set_rxmode(struct port_info *p)
1233 1.1.2.2 uebayasi {
1234 1.1.2.2 uebayasi struct t3_rx_mode rm;
1235 1.1.2.2 uebayasi struct cmac *mac = &p->mac;
1236 1.1.2.2 uebayasi
1237 1.1.2.2 uebayasi PORT_LOCK_ASSERT_OWNED(p);
1238 1.1.2.2 uebayasi
1239 1.1.2.2 uebayasi t3_init_rx_mode(&rm, p);
1240 1.1.2.2 uebayasi t3_mac_set_rx_mode(mac, &rm);
1241 1.1.2.2 uebayasi }
1242 1.1.2.2 uebayasi
1243 1.1.2.2 uebayasi static void
1244 1.1.2.2 uebayasi cxgb_stop_locked(struct port_info *p)
1245 1.1.2.2 uebayasi {
1246 1.1.2.2 uebayasi struct ifnet *ifp;
1247 1.1.2.2 uebayasi
1248 1.1.2.2 uebayasi PORT_LOCK_ASSERT_OWNED(p);
1249 1.1.2.2 uebayasi ADAPTER_LOCK_ASSERT_NOTOWNED(p->adapter);
1250 1.1.2.2 uebayasi
1251 1.1.2.2 uebayasi ifp = p->ifp;
1252 1.1.2.2 uebayasi
1253 1.1.2.2 uebayasi t3_port_intr_disable(p->adapter, p->port_id);
1254 1.1.2.2 uebayasi ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
1255 1.1.2.2 uebayasi p->phy.ops->power_down(&p->phy, 1);
1256 1.1.2.2 uebayasi t3_mac_disable(&p->mac, MAC_DIRECTION_TX | MAC_DIRECTION_RX);
1257 1.1.2.2 uebayasi
1258 1.1.2.2 uebayasi ADAPTER_LOCK(p->adapter);
1259 1.1.2.2 uebayasi clrbit(&p->adapter->open_device_map, p->port_id);
1260 1.1.2.2 uebayasi
1261 1.1.2.2 uebayasi
1262 1.1.2.2 uebayasi if (p->adapter->open_device_map == 0) {
1263 1.1.2.2 uebayasi cxgb_down_locked(p->adapter);
1264 1.1.2.2 uebayasi } else
1265 1.1.2.2 uebayasi ADAPTER_UNLOCK(p->adapter);
1266 1.1.2.2 uebayasi
1267 1.1.2.2 uebayasi }
1268 1.1.2.2 uebayasi
1269 1.1.2.2 uebayasi static int
1270 1.1.2.2 uebayasi cxgb_set_mtu(struct port_info *p, int mtu)
1271 1.1.2.2 uebayasi {
1272 1.1.2.2 uebayasi struct ifnet *ifp = p->ifp;
1273 1.1.2.2 uebayasi struct ifreq ifr;
1274 1.1.2.2 uebayasi int error = 0;
1275 1.1.2.2 uebayasi
1276 1.1.2.2 uebayasi ifr.ifr_mtu = mtu;
1277 1.1.2.2 uebayasi
1278 1.1.2.2 uebayasi if ((mtu < ETHERMIN) || (mtu > ETHER_MAX_LEN_JUMBO))
1279 1.1.2.2 uebayasi error = EINVAL;
1280 1.1.2.2 uebayasi else if ((error = ifioctl_common(ifp, SIOCSIFMTU, &ifr)) == ENETRESET) {
1281 1.1.2.2 uebayasi error = 0;
1282 1.1.2.2 uebayasi PORT_LOCK(p);
1283 1.1.2.2 uebayasi if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
1284 1.1.2.2 uebayasi callout_stop(&p->adapter->cxgb_tick_ch);
1285 1.1.2.2 uebayasi cxgb_stop_locked(p);
1286 1.1.2.2 uebayasi cxgb_init_locked(p);
1287 1.1.2.2 uebayasi }
1288 1.1.2.2 uebayasi PORT_UNLOCK(p);
1289 1.1.2.2 uebayasi }
1290 1.1.2.2 uebayasi return (error);
1291 1.1.2.2 uebayasi }
1292 1.1.2.2 uebayasi
1293 1.1.2.2 uebayasi static int
1294 1.1.2.2 uebayasi cxgb_ioctl(struct ifnet *ifp, unsigned long command, void *data)
1295 1.1.2.2 uebayasi {
1296 1.1.2.2 uebayasi struct port_info *p = ifp->if_softc;
1297 1.1.2.2 uebayasi struct ifaddr *ifa = (struct ifaddr *)data;
1298 1.1.2.2 uebayasi struct ifreq *ifr = (struct ifreq *)data;
1299 1.1.2.2 uebayasi int flags, error = 0;
1300 1.1.2.2 uebayasi
1301 1.1.2.2 uebayasi /*
1302 1.1.2.2 uebayasi * XXX need to check that we aren't in the middle of an unload
1303 1.1.2.2 uebayasi */
1304 1.1.2.2 uebayasi printf("cxgb_ioctl(%d): command=%08lx\n", __LINE__, command);
1305 1.1.2.2 uebayasi switch (command) {
1306 1.1.2.2 uebayasi case SIOCSIFMTU:
1307 1.1.2.2 uebayasi error = cxgb_set_mtu(p, ifr->ifr_mtu);
1308 1.1.2.2 uebayasi printf("SIOCSIFMTU: error=%d\n", error);
1309 1.1.2.2 uebayasi break;
1310 1.1.2.2 uebayasi case SIOCINITIFADDR:
1311 1.1.2.2 uebayasi printf("SIOCINITIFADDR:\n");
1312 1.1.2.2 uebayasi PORT_LOCK(p);
1313 1.1.2.2 uebayasi if (ifa->ifa_addr->sa_family == AF_INET) {
1314 1.1.2.2 uebayasi ifp->if_flags |= IFF_UP;
1315 1.1.2.2 uebayasi if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
1316 1.1.2.2 uebayasi cxgb_init_locked(p);
1317 1.1.2.2 uebayasi arp_ifinit(ifp, ifa);
1318 1.1.2.2 uebayasi } else
1319 1.1.2.2 uebayasi error = ether_ioctl(ifp, command, data);
1320 1.1.2.2 uebayasi PORT_UNLOCK(p);
1321 1.1.2.2 uebayasi break;
1322 1.1.2.2 uebayasi case SIOCSIFFLAGS:
1323 1.1.2.2 uebayasi printf("SIOCSIFFLAGS:\n");
1324 1.1.2.2 uebayasi #if 0
1325 1.1.2.2 uebayasi if ((error = ifioctl_common(ifp, cmd, data)) != 0)
1326 1.1.2.2 uebayasi break;
1327 1.1.2.2 uebayasi #endif
1328 1.1.2.2 uebayasi callout_drain(&p->adapter->cxgb_tick_ch);
1329 1.1.2.2 uebayasi PORT_LOCK(p);
1330 1.1.2.2 uebayasi if (ifp->if_flags & IFF_UP) {
1331 1.1.2.2 uebayasi if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
1332 1.1.2.2 uebayasi flags = p->if_flags;
1333 1.1.2.2 uebayasi if (((ifp->if_flags ^ flags) & IFF_PROMISC) ||
1334 1.1.2.2 uebayasi ((ifp->if_flags ^ flags) & IFF_ALLMULTI))
1335 1.1.2.2 uebayasi cxgb_set_rxmode(p);
1336 1.1.2.2 uebayasi } else
1337 1.1.2.2 uebayasi cxgb_init_locked(p);
1338 1.1.2.2 uebayasi p->if_flags = ifp->if_flags;
1339 1.1.2.2 uebayasi } else if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1340 1.1.2.2 uebayasi cxgb_stop_locked(p);
1341 1.1.2.2 uebayasi
1342 1.1.2.2 uebayasi if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
1343 1.1.2.2 uebayasi adapter_t *sc = p->adapter;
1344 1.1.2.2 uebayasi callout_reset(&sc->cxgb_tick_ch,
1345 1.1.2.2 uebayasi sc->params.stats_update_period * hz,
1346 1.1.2.2 uebayasi cxgb_tick, sc);
1347 1.1.2.2 uebayasi }
1348 1.1.2.2 uebayasi PORT_UNLOCK(p);
1349 1.1.2.2 uebayasi break;
1350 1.1.2.2 uebayasi case SIOCSIFMEDIA:
1351 1.1.2.2 uebayasi printf("SIOCSIFMEDIA:\n");
1352 1.1.2.2 uebayasi case SIOCGIFMEDIA:
1353 1.1.2.2 uebayasi error = ifmedia_ioctl(ifp, ifr, &p->media, command);
1354 1.1.2.2 uebayasi printf("SIOCGIFMEDIA: error=%d\n", error);
1355 1.1.2.2 uebayasi break;
1356 1.1.2.2 uebayasi default:
1357 1.1.2.2 uebayasi printf("Dir = %x Len = %x Group = '%c' Num = %x\n",
1358 1.1.2.2 uebayasi (unsigned int)(command&0xe0000000)>>28, (unsigned int)(command&0x1fff0000)>>16,
1359 1.1.2.2 uebayasi (unsigned int)(command&0xff00)>>8, (unsigned int)command&0xff);
1360 1.1.2.2 uebayasi if ((error = ether_ioctl(ifp, command, data)) != ENETRESET)
1361 1.1.2.2 uebayasi break;
1362 1.1.2.2 uebayasi error = 0;
1363 1.1.2.2 uebayasi break;
1364 1.1.2.2 uebayasi }
1365 1.1.2.2 uebayasi return (error);
1366 1.1.2.2 uebayasi }
1367 1.1.2.2 uebayasi
1368 1.1.2.2 uebayasi static int
1369 1.1.2.2 uebayasi cxgb_start_tx(struct ifnet *ifp, uint32_t txmax)
1370 1.1.2.2 uebayasi {
1371 1.1.2.2 uebayasi struct sge_qset *qs;
1372 1.1.2.2 uebayasi struct sge_txq *txq;
1373 1.1.2.2 uebayasi struct port_info *p = ifp->if_softc;
1374 1.1.2.2 uebayasi struct mbuf *m = NULL;
1375 1.1.2.2 uebayasi int err, in_use_init, free_it;
1376 1.1.2.2 uebayasi
1377 1.1.2.2 uebayasi if (!p->link_config.link_ok)
1378 1.1.2.2 uebayasi {
1379 1.1.2.2 uebayasi return (ENXIO);
1380 1.1.2.2 uebayasi }
1381 1.1.2.2 uebayasi
1382 1.1.2.2 uebayasi if (IFQ_IS_EMPTY(&ifp->if_snd))
1383 1.1.2.2 uebayasi {
1384 1.1.2.2 uebayasi return (ENOBUFS);
1385 1.1.2.2 uebayasi }
1386 1.1.2.2 uebayasi
1387 1.1.2.2 uebayasi qs = &p->adapter->sge.qs[p->first_qset];
1388 1.1.2.2 uebayasi txq = &qs->txq[TXQ_ETH];
1389 1.1.2.2 uebayasi err = 0;
1390 1.1.2.2 uebayasi
1391 1.1.2.2 uebayasi if (txq->flags & TXQ_TRANSMITTING)
1392 1.1.2.2 uebayasi {
1393 1.1.2.2 uebayasi return (EINPROGRESS);
1394 1.1.2.2 uebayasi }
1395 1.1.2.2 uebayasi
1396 1.1.2.2 uebayasi mtx_lock(&txq->lock);
1397 1.1.2.2 uebayasi txq->flags |= TXQ_TRANSMITTING;
1398 1.1.2.2 uebayasi in_use_init = txq->in_use;
1399 1.1.2.2 uebayasi while ((txq->in_use - in_use_init < txmax) &&
1400 1.1.2.2 uebayasi (txq->size > txq->in_use + TX_MAX_DESC)) {
1401 1.1.2.2 uebayasi free_it = 0;
1402 1.1.2.2 uebayasi IFQ_DEQUEUE(&ifp->if_snd, m);
1403 1.1.2.2 uebayasi if (m == NULL)
1404 1.1.2.2 uebayasi break;
1405 1.1.2.2 uebayasi /*
1406 1.1.2.2 uebayasi * Convert chain to M_IOVEC
1407 1.1.2.2 uebayasi */
1408 1.1.2.2 uebayasi KASSERT((m->m_flags & M_IOVEC) == 0);
1409 1.1.2.2 uebayasi #ifdef notyet
1410 1.1.2.2 uebayasi m0 = m;
1411 1.1.2.2 uebayasi if (collapse_mbufs && m->m_pkthdr.len > MCLBYTES &&
1412 1.1.2.2 uebayasi m_collapse(m, TX_MAX_SEGS, &m0) == EFBIG) {
1413 1.1.2.2 uebayasi if ((m0 = m_defrag(m, M_NOWAIT)) != NULL) {
1414 1.1.2.2 uebayasi m = m0;
1415 1.1.2.2 uebayasi m_collapse(m, TX_MAX_SEGS, &m0);
1416 1.1.2.2 uebayasi } else
1417 1.1.2.2 uebayasi break;
1418 1.1.2.2 uebayasi }
1419 1.1.2.2 uebayasi m = m0;
1420 1.1.2.2 uebayasi #endif
1421 1.1.2.2 uebayasi if ((err = t3_encap(p, &m, &free_it)) != 0)
1422 1.1.2.2 uebayasi {
1423 1.1.2.2 uebayasi printf("t3_encap() returned %d\n", err);
1424 1.1.2.2 uebayasi break;
1425 1.1.2.2 uebayasi }
1426 1.1.2.2 uebayasi // bpf_mtap(ifp, m);
1427 1.1.2.2 uebayasi if (free_it)
1428 1.1.2.2 uebayasi {
1429 1.1.2.2 uebayasi m_freem(m);
1430 1.1.2.2 uebayasi }
1431 1.1.2.2 uebayasi }
1432 1.1.2.2 uebayasi txq->flags &= ~TXQ_TRANSMITTING;
1433 1.1.2.2 uebayasi mtx_unlock(&txq->lock);
1434 1.1.2.2 uebayasi
1435 1.1.2.2 uebayasi if (__predict_false(err)) {
1436 1.1.2.2 uebayasi if (err == ENOMEM) {
1437 1.1.2.2 uebayasi ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1438 1.1.2.2 uebayasi // XXXXXXXXXX lock/unlock??
1439 1.1.2.2 uebayasi IF_PREPEND(&ifp->if_snd, m);
1440 1.1.2.2 uebayasi }
1441 1.1.2.2 uebayasi }
1442 1.1.2.2 uebayasi if (err == 0 && m == NULL)
1443 1.1.2.2 uebayasi err = ENOBUFS;
1444 1.1.2.2 uebayasi else if ((err == 0) && (txq->size <= txq->in_use + TX_MAX_DESC) &&
1445 1.1.2.2 uebayasi (ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) {
1446 1.1.2.2 uebayasi ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1447 1.1.2.2 uebayasi err = ENOSPC;
1448 1.1.2.2 uebayasi }
1449 1.1.2.2 uebayasi return (err);
1450 1.1.2.2 uebayasi }
1451 1.1.2.2 uebayasi
1452 1.1.2.2 uebayasi static void
1453 1.1.2.2 uebayasi cxgb_start_proc(struct work *wk, void *arg)
1454 1.1.2.2 uebayasi {
1455 1.1.2.2 uebayasi struct ifnet *ifp = arg;
1456 1.1.2.2 uebayasi struct port_info *pi = ifp->if_softc;
1457 1.1.2.2 uebayasi struct sge_qset *qs;
1458 1.1.2.2 uebayasi struct sge_txq *txq;
1459 1.1.2.2 uebayasi int error;
1460 1.1.2.2 uebayasi
1461 1.1.2.2 uebayasi qs = &pi->adapter->sge.qs[pi->first_qset];
1462 1.1.2.2 uebayasi txq = &qs->txq[TXQ_ETH];
1463 1.1.2.2 uebayasi
1464 1.1.2.2 uebayasi do {
1465 1.1.2.2 uebayasi if (desc_reclaimable(txq) > TX_CLEAN_MAX_DESC >> 2)
1466 1.1.2.2 uebayasi workqueue_enqueue(pi->timer_reclaim_task.wq, &pi->timer_reclaim_task.w, NULL);
1467 1.1.2.2 uebayasi
1468 1.1.2.2 uebayasi error = cxgb_start_tx(ifp, TX_START_MAX_DESC);
1469 1.1.2.2 uebayasi } while (error == 0);
1470 1.1.2.2 uebayasi }
1471 1.1.2.2 uebayasi
1472 1.1.2.2 uebayasi static void
1473 1.1.2.2 uebayasi cxgb_start(struct ifnet *ifp)
1474 1.1.2.2 uebayasi {
1475 1.1.2.2 uebayasi struct port_info *pi = ifp->if_softc;
1476 1.1.2.2 uebayasi struct sge_qset *qs;
1477 1.1.2.2 uebayasi struct sge_txq *txq;
1478 1.1.2.2 uebayasi int err;
1479 1.1.2.2 uebayasi
1480 1.1.2.2 uebayasi qs = &pi->adapter->sge.qs[pi->first_qset];
1481 1.1.2.2 uebayasi txq = &qs->txq[TXQ_ETH];
1482 1.1.2.2 uebayasi
1483 1.1.2.2 uebayasi if (desc_reclaimable(txq) > TX_CLEAN_MAX_DESC >> 2)
1484 1.1.2.2 uebayasi workqueue_enqueue(pi->timer_reclaim_task.wq, &pi->timer_reclaim_task.w, NULL);
1485 1.1.2.2 uebayasi
1486 1.1.2.2 uebayasi err = cxgb_start_tx(ifp, TX_START_MAX_DESC);
1487 1.1.2.2 uebayasi
1488 1.1.2.2 uebayasi if (err == 0)
1489 1.1.2.2 uebayasi workqueue_enqueue(pi->start_task.wq, &pi->start_task.w, NULL);
1490 1.1.2.2 uebayasi }
1491 1.1.2.2 uebayasi
1492 1.1.2.2 uebayasi static void
1493 1.1.2.2 uebayasi cxgb_stop(struct ifnet *ifp, int reason)
1494 1.1.2.2 uebayasi {
1495 1.1.2.2 uebayasi struct port_info *pi = ifp->if_softc;
1496 1.1.2.2 uebayasi
1497 1.1.2.2 uebayasi printf("cxgb_stop(): pi=%p, reason=%d\n", pi, reason);
1498 1.1.2.2 uebayasi INT3;
1499 1.1.2.2 uebayasi }
1500 1.1.2.2 uebayasi
1501 1.1.2.2 uebayasi static int
1502 1.1.2.2 uebayasi cxgb_media_change(struct ifnet *ifp)
1503 1.1.2.2 uebayasi {
1504 1.1.2.2 uebayasi printf("media change not supported: ifp=%p\n", ifp);
1505 1.1.2.2 uebayasi return (ENXIO);
1506 1.1.2.2 uebayasi }
1507 1.1.2.2 uebayasi
1508 1.1.2.2 uebayasi static void
1509 1.1.2.2 uebayasi cxgb_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
1510 1.1.2.2 uebayasi {
1511 1.1.2.2 uebayasi struct port_info *p;
1512 1.1.2.2 uebayasi
1513 1.1.2.2 uebayasi p = ifp->if_softc;
1514 1.1.2.2 uebayasi
1515 1.1.2.2 uebayasi ifmr->ifm_status = IFM_AVALID;
1516 1.1.2.2 uebayasi ifmr->ifm_active = IFM_ETHER;
1517 1.1.2.2 uebayasi
1518 1.1.2.2 uebayasi if (!p->link_config.link_ok)
1519 1.1.2.2 uebayasi return;
1520 1.1.2.2 uebayasi
1521 1.1.2.2 uebayasi ifmr->ifm_status |= IFM_ACTIVE;
1522 1.1.2.2 uebayasi
1523 1.1.2.2 uebayasi switch (p->link_config.speed) {
1524 1.1.2.2 uebayasi case 10:
1525 1.1.2.2 uebayasi ifmr->ifm_active |= IFM_10_T;
1526 1.1.2.2 uebayasi break;
1527 1.1.2.2 uebayasi case 100:
1528 1.1.2.2 uebayasi ifmr->ifm_active |= IFM_100_TX;
1529 1.1.2.2 uebayasi break;
1530 1.1.2.2 uebayasi case 1000:
1531 1.1.2.2 uebayasi ifmr->ifm_active |= IFM_1000_T;
1532 1.1.2.2 uebayasi break;
1533 1.1.2.2 uebayasi }
1534 1.1.2.2 uebayasi
1535 1.1.2.2 uebayasi if (p->link_config.duplex)
1536 1.1.2.2 uebayasi ifmr->ifm_active |= IFM_FDX;
1537 1.1.2.2 uebayasi else
1538 1.1.2.2 uebayasi ifmr->ifm_active |= IFM_HDX;
1539 1.1.2.2 uebayasi }
1540 1.1.2.2 uebayasi
1541 1.1.2.2 uebayasi static int
1542 1.1.2.2 uebayasi cxgb_async_intr(void *data)
1543 1.1.2.2 uebayasi {
1544 1.1.2.2 uebayasi adapter_t *sc = data;
1545 1.1.2.2 uebayasi
1546 1.1.2.2 uebayasi if (cxgb_debug)
1547 1.1.2.2 uebayasi device_printf(sc->dev, "cxgb_async_intr\n");
1548 1.1.2.2 uebayasi /*
1549 1.1.2.2 uebayasi * May need to sleep - defer to taskqueue
1550 1.1.2.2 uebayasi */
1551 1.1.2.2 uebayasi workqueue_enqueue(sc->slow_intr_task.wq, &sc->slow_intr_task.w, NULL);
1552 1.1.2.2 uebayasi
1553 1.1.2.2 uebayasi return (1);
1554 1.1.2.2 uebayasi }
1555 1.1.2.2 uebayasi
1556 1.1.2.2 uebayasi static void
1557 1.1.2.2 uebayasi cxgb_ext_intr_handler(struct work *wk, void *arg)
1558 1.1.2.2 uebayasi {
1559 1.1.2.2 uebayasi adapter_t *sc = (adapter_t *)arg;
1560 1.1.2.2 uebayasi
1561 1.1.2.2 uebayasi if (cxgb_debug)
1562 1.1.2.2 uebayasi printf("cxgb_ext_intr_handler\n");
1563 1.1.2.2 uebayasi
1564 1.1.2.2 uebayasi t3_phy_intr_handler(sc);
1565 1.1.2.2 uebayasi
1566 1.1.2.2 uebayasi /* Now reenable external interrupts */
1567 1.1.2.2 uebayasi ADAPTER_LOCK(sc);
1568 1.1.2.2 uebayasi if (sc->slow_intr_mask) {
1569 1.1.2.2 uebayasi sc->slow_intr_mask |= F_T3DBG;
1570 1.1.2.2 uebayasi t3_write_reg(sc, A_PL_INT_CAUSE0, F_T3DBG);
1571 1.1.2.2 uebayasi t3_write_reg(sc, A_PL_INT_ENABLE0, sc->slow_intr_mask);
1572 1.1.2.2 uebayasi }
1573 1.1.2.2 uebayasi ADAPTER_UNLOCK(sc);
1574 1.1.2.2 uebayasi }
1575 1.1.2.2 uebayasi
1576 1.1.2.2 uebayasi static void
1577 1.1.2.2 uebayasi check_link_status(adapter_t *sc)
1578 1.1.2.2 uebayasi {
1579 1.1.2.2 uebayasi int i;
1580 1.1.2.2 uebayasi
1581 1.1.2.2 uebayasi for (i = 0; i < (sc)->params.nports; ++i) {
1582 1.1.2.2 uebayasi struct port_info *p = &sc->port[i];
1583 1.1.2.2 uebayasi
1584 1.1.2.2 uebayasi if (!(p->port_type->caps & SUPPORTED_IRQ))
1585 1.1.2.2 uebayasi t3_link_changed(sc, i);
1586 1.1.2.2 uebayasi p->ifp->if_baudrate = p->link_config.speed * 1000000;
1587 1.1.2.2 uebayasi }
1588 1.1.2.2 uebayasi }
1589 1.1.2.2 uebayasi
1590 1.1.2.2 uebayasi static void
1591 1.1.2.2 uebayasi check_t3b2_mac(struct adapter *adapter)
1592 1.1.2.2 uebayasi {
1593 1.1.2.2 uebayasi int i;
1594 1.1.2.2 uebayasi
1595 1.1.2.2 uebayasi for_each_port(adapter, i) {
1596 1.1.2.2 uebayasi struct port_info *p = &adapter->port[i];
1597 1.1.2.2 uebayasi struct ifnet *ifp = p->ifp;
1598 1.1.2.2 uebayasi int status;
1599 1.1.2.2 uebayasi
1600 1.1.2.2 uebayasi if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
1601 1.1.2.2 uebayasi continue;
1602 1.1.2.2 uebayasi
1603 1.1.2.2 uebayasi status = 0;
1604 1.1.2.2 uebayasi PORT_LOCK(p);
1605 1.1.2.2 uebayasi if ((ifp->if_drv_flags & IFF_DRV_RUNNING))
1606 1.1.2.2 uebayasi status = t3b2_mac_watchdog_task(&p->mac);
1607 1.1.2.2 uebayasi if (status == 1)
1608 1.1.2.2 uebayasi p->mac.stats.num_toggled++;
1609 1.1.2.2 uebayasi else if (status == 2) {
1610 1.1.2.2 uebayasi struct cmac *mac = &p->mac;
1611 1.1.2.2 uebayasi
1612 1.1.2.2 uebayasi t3_mac_set_mtu(mac, ifp->if_mtu + ETHER_HDR_LEN
1613 1.1.2.2 uebayasi + ETHER_VLAN_ENCAP_LEN);
1614 1.1.2.2 uebayasi t3_mac_set_address(mac, 0, p->hw_addr);
1615 1.1.2.2 uebayasi cxgb_set_rxmode(p);
1616 1.1.2.2 uebayasi t3_link_start(&p->phy, mac, &p->link_config);
1617 1.1.2.2 uebayasi t3_mac_enable(mac, MAC_DIRECTION_RX | MAC_DIRECTION_TX);
1618 1.1.2.2 uebayasi t3_port_intr_enable(adapter, p->port_id);
1619 1.1.2.2 uebayasi p->mac.stats.num_resets++;
1620 1.1.2.2 uebayasi }
1621 1.1.2.2 uebayasi PORT_UNLOCK(p);
1622 1.1.2.2 uebayasi }
1623 1.1.2.2 uebayasi }
1624 1.1.2.2 uebayasi
1625 1.1.2.2 uebayasi static void
1626 1.1.2.2 uebayasi cxgb_tick(void *arg)
1627 1.1.2.2 uebayasi {
1628 1.1.2.2 uebayasi adapter_t *sc = (adapter_t *)arg;
1629 1.1.2.2 uebayasi
1630 1.1.2.2 uebayasi workqueue_enqueue(sc->tick_task.wq, &sc->tick_task.w, NULL);
1631 1.1.2.2 uebayasi
1632 1.1.2.2 uebayasi if (sc->open_device_map != 0)
1633 1.1.2.2 uebayasi callout_reset(&sc->cxgb_tick_ch, sc->params.stats_update_period * hz,
1634 1.1.2.2 uebayasi cxgb_tick, sc);
1635 1.1.2.2 uebayasi }
1636 1.1.2.2 uebayasi
1637 1.1.2.2 uebayasi static void
1638 1.1.2.2 uebayasi cxgb_tick_handler(struct work *wk, void *arg)
1639 1.1.2.2 uebayasi {
1640 1.1.2.2 uebayasi adapter_t *sc = (adapter_t *)arg;
1641 1.1.2.2 uebayasi const struct adapter_params *p = &sc->params;
1642 1.1.2.2 uebayasi
1643 1.1.2.2 uebayasi ADAPTER_LOCK(sc);
1644 1.1.2.2 uebayasi if (p->linkpoll_period)
1645 1.1.2.2 uebayasi check_link_status(sc);
1646 1.1.2.2 uebayasi
1647 1.1.2.2 uebayasi /*
1648 1.1.2.2 uebayasi * adapter lock can currently only be acquire after the
1649 1.1.2.2 uebayasi * port lock
1650 1.1.2.2 uebayasi */
1651 1.1.2.2 uebayasi ADAPTER_UNLOCK(sc);
1652 1.1.2.2 uebayasi
1653 1.1.2.2 uebayasi if (p->rev == T3_REV_B2 && p->nports < 4)
1654 1.1.2.2 uebayasi check_t3b2_mac(sc);
1655 1.1.2.2 uebayasi }
1656 1.1.2.2 uebayasi
1657 1.1.2.2 uebayasi static void
1658 1.1.2.2 uebayasi touch_bars(device_t dev)
1659 1.1.2.2 uebayasi {
1660 1.1.2.2 uebayasi /*
1661 1.1.2.2 uebayasi * Don't enable yet
1662 1.1.2.2 uebayasi */
1663 1.1.2.2 uebayasi #if !defined(__LP64__) && 0
1664 1.1.2.2 uebayasi u32 v;
1665 1.1.2.2 uebayasi
1666 1.1.2.2 uebayasi pci_read_config_dword(pdev, PCI_BASE_ADDRESS_1, &v);
1667 1.1.2.2 uebayasi pci_write_config_dword(pdev, PCI_BASE_ADDRESS_1, v);
1668 1.1.2.2 uebayasi pci_read_config_dword(pdev, PCI_BASE_ADDRESS_3, &v);
1669 1.1.2.2 uebayasi pci_write_config_dword(pdev, PCI_BASE_ADDRESS_3, v);
1670 1.1.2.2 uebayasi pci_read_config_dword(pdev, PCI_BASE_ADDRESS_5, &v);
1671 1.1.2.2 uebayasi pci_write_config_dword(pdev, PCI_BASE_ADDRESS_5, v);
1672 1.1.2.2 uebayasi #endif
1673 1.1.2.2 uebayasi }
1674 1.1.2.2 uebayasi
1675 1.1.2.2 uebayasi static __inline void
1676 1.1.2.2 uebayasi reg_block_dump(struct adapter *ap, uint8_t *buf, unsigned int start,
1677 1.1.2.2 uebayasi unsigned int end)
1678 1.1.2.2 uebayasi {
1679 1.1.2.2 uebayasi uint32_t *p = (uint32_t *)buf + start;
1680 1.1.2.2 uebayasi
1681 1.1.2.2 uebayasi for ( ; start <= end; start += sizeof(uint32_t))
1682 1.1.2.2 uebayasi *p++ = t3_read_reg(ap, start);
1683 1.1.2.2 uebayasi }
1684 1.1.2.2 uebayasi
1685