cxgb_osdep.c revision 1.2 1 1.1 jklos /**************************************************************************
2 1.1 jklos
3 1.1 jklos Copyright (c) 2007, Chelsio Inc.
4 1.1 jklos All rights reserved.
5 1.1 jklos
6 1.1 jklos Redistribution and use in source and binary forms, with or without
7 1.1 jklos modification, are permitted provided that the following conditions are met:
8 1.1 jklos
9 1.1 jklos 1. Redistributions of source code must retain the above copyright notice,
10 1.1 jklos this list of conditions and the following disclaimer.
11 1.1 jklos
12 1.1 jklos 2. Neither the name of the Chelsio Corporation nor the names of its
13 1.1 jklos contributors may be used to endorse or promote products derived from
14 1.1 jklos this software without specific prior written permission.
15 1.1 jklos
16 1.1 jklos THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 1.1 jklos AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 1.1 jklos IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 1.1 jklos ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 1.1 jklos LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 1.1 jklos CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 1.1 jklos SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 1.1 jklos INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 1.1 jklos CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 1.1 jklos ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 1.1 jklos POSSIBILITY OF SUCH DAMAGE.
27 1.1 jklos
28 1.1 jklos ***************************************************************************/
29 1.1 jklos
30 1.1 jklos #include <sys/cdefs.h>
31 1.1 jklos
32 1.1 jklos #include <sys/param.h>
33 1.1 jklos #include <sys/systm.h>
34 1.1 jklos #include <sys/kernel.h>
35 1.1 jklos #include <sys/conf.h>
36 1.2 dyoung #include <sys/bus.h>
37 1.1 jklos #include <sys/ioccom.h>
38 1.1 jklos #include <sys/mbuf.h>
39 1.1 jklos #include <sys/socket.h>
40 1.1 jklos #include <sys/sockio.h>
41 1.1 jklos #include <sys/sysctl.h>
42 1.1 jklos #include <sys/queue.h>
43 1.1 jklos
44 1.1 jklos #include <net/bpf.h>
45 1.1 jklos #include <net/if.h>
46 1.1 jklos #include <net/if_arp.h>
47 1.1 jklos #include <net/if_dl.h>
48 1.1 jklos #include <net/if_media.h>
49 1.1 jklos #include <net/if_types.h>
50 1.1 jklos
51 1.1 jklos #include <netinet/in_systm.h>
52 1.1 jklos #include <netinet/in.h>
53 1.1 jklos #include <netinet/ip.h>
54 1.1 jklos #include <netinet/tcp.h>
55 1.1 jklos #include <netinet/udp.h>
56 1.1 jklos
57 1.1 jklos #include <dev/pci/pcireg.h>
58 1.1 jklos #include <dev/pci/pcivar.h>
59 1.1 jklos
60 1.1 jklos #include <dev/pci/cxgb/cxgb_include.h>
61 1.1 jklos #include <altq/altq_conf.h>
62 1.1 jklos
63 1.1 jklos int cxgb_initialized = FALSE;
64 1.1 jklos
65 1.1 jklos int atomic_fetchadd_int(volatile int *p, int v)
66 1.1 jklos {
67 1.1 jklos int tmp = *p;
68 1.1 jklos *p += v;
69 1.1 jklos return (tmp);
70 1.1 jklos }
71 1.1 jklos
72 1.1 jklos #if 0
73 1.1 jklos int atomic_add_int(volatile int *p, int v)
74 1.1 jklos {
75 1.1 jklos return (*p += v);
76 1.1 jklos }
77 1.1 jklos #endif
78 1.1 jklos
79 1.1 jklos int atomic_load_acq_int(volatile int *p)
80 1.1 jklos {
81 1.1 jklos return (*p);
82 1.1 jklos }
83 1.1 jklos
84 1.1 jklos void atomic_store_rel_int(volatile int *p, int v)
85 1.1 jklos {
86 1.1 jklos *p = v;
87 1.1 jklos }
88 1.1 jklos
89 1.1 jklos u_short in_cksum_hdr(struct ip *ih)
90 1.1 jklos {
91 1.1 jklos u_long sum = 0;
92 1.1 jklos u_short *p = (u_short *)ih;
93 1.1 jklos int i;
94 1.1 jklos
95 1.1 jklos i = ih->ip_hl*2;
96 1.1 jklos while (i--)
97 1.1 jklos sum += *p++;
98 1.1 jklos
99 1.1 jklos if (sum > 0xffff)
100 1.1 jklos sum -= 0xffff;
101 1.1 jklos
102 1.1 jklos return (~sum);
103 1.1 jklos }
104 1.1 jklos
105 1.1 jklos void m_cljset(struct mbuf *m, void *cl, int type)
106 1.1 jklos {
107 1.1 jklos MEXTADD(m, cl, m->m_len, M_DEVBUF, NULL, NULL);
108 1.1 jklos }
109 1.1 jklos
110 1.1 jklos int
111 1.1 jklos _m_explode(struct mbuf *m)
112 1.1 jklos {
113 1.1 jklos int i, offset, type, first, len;
114 1.1 jklos uint8_t *cl;
115 1.1 jklos struct mbuf *m0, *head = NULL;
116 1.1 jklos struct mbuf_vec *mv;
117 1.1 jklos
118 1.1 jklos #ifdef INVARIANTS
119 1.1 jklos len = m->m_len;
120 1.1 jklos m0 = m->m_next;
121 1.1 jklos while (m0) {
122 1.1 jklos KASSERT((m0->m_flags & M_PKTHDR) == 0,
123 1.1 jklos ("pkthdr set on intermediate mbuf - pre"));
124 1.1 jklos len += m0->m_len;
125 1.1 jklos m0 = m0->m_next;
126 1.1 jklos
127 1.1 jklos }
128 1.1 jklos if (len != m->m_pkthdr.len)
129 1.1 jklos panic("at start len=%d pktlen=%d", len, m->m_pkthdr.len);
130 1.1 jklos #endif
131 1.1 jklos mv = (struct mbuf_vec *)((m)->m_pktdat);
132 1.1 jklos first = mv->mv_first;
133 1.1 jklos for (i = mv->mv_count + first - 1; i > first; i--) {
134 1.1 jklos type = mbuf_vec_get_type(mv, i);
135 1.1 jklos cl = mv->mv_vec[i].mi_base;
136 1.1 jklos offset = mv->mv_vec[i].mi_offset;
137 1.1 jklos len = mv->mv_vec[i].mi_len;
138 1.1 jklos #if 0
139 1.1 jklos if (__predict_false(type == EXT_MBUF)) {
140 1.1 jklos m0 = (struct mbuf *)cl;
141 1.1 jklos KASSERT((m0->m_flags & M_EXT) == 0);
142 1.1 jklos m0->m_len = len;
143 1.1 jklos m0->m_data = cl + offset;
144 1.1 jklos goto skip_cluster;
145 1.1 jklos
146 1.1 jklos } else
147 1.1 jklos #endif
148 1.1 jklos if ((m0 = m_get(M_NOWAIT, MT_DATA)) == NULL) {
149 1.1 jklos /*
150 1.1 jklos * Check for extra memory leaks
151 1.1 jklos */
152 1.1 jklos m_freem(head);
153 1.1 jklos return (ENOMEM);
154 1.1 jklos }
155 1.1 jklos m0->m_flags = 0;
156 1.1 jklos
157 1.1 jklos m0->m_len = mv->mv_vec[i].mi_len;
158 1.1 jklos m_cljset(m0, (uint8_t *)cl, type);
159 1.1 jklos if (offset)
160 1.1 jklos m_adj(m0, offset);
161 1.1 jklos // skip_cluster:
162 1.1 jklos m0->m_next = head;
163 1.1 jklos m->m_len -= m0->m_len;
164 1.1 jklos head = m0;
165 1.1 jklos }
166 1.1 jklos offset = mv->mv_vec[first].mi_offset;
167 1.1 jklos cl = mv->mv_vec[first].mi_base;
168 1.1 jklos type = mbuf_vec_get_type(mv, first);
169 1.1 jklos m->m_flags &= ~(M_IOVEC);
170 1.1 jklos m_cljset(m, cl, type);
171 1.1 jklos if (offset)
172 1.1 jklos m_adj(m, offset);
173 1.1 jklos m->m_next = head;
174 1.1 jklos head = m;
175 1.1 jklos M_SANITY(m, 0);
176 1.1 jklos
177 1.1 jklos return (0);
178 1.1 jklos }
179 1.1 jklos
180 1.1 jklos /*
181 1.1 jklos * Allocate a chunk of memory using kmalloc or, if that fails, vmalloc.
182 1.1 jklos * The allocated memory is cleared.
183 1.1 jklos */
184 1.1 jklos void *
185 1.1 jklos cxgb_alloc_mem(unsigned long size)
186 1.1 jklos {
187 1.1 jklos return malloc(size, M_DEVBUF, M_ZERO);
188 1.1 jklos }
189 1.1 jklos
190 1.1 jklos /*
191 1.1 jklos * Free memory allocated through t3_alloc_mem().
192 1.1 jklos */
193 1.1 jklos void
194 1.1 jklos cxgb_free_mem(void *addr)
195 1.1 jklos {
196 1.1 jklos free(addr, M_DEVBUF);
197 1.1 jklos }
198 1.1 jklos
199 1.1 jklos void pci_enable_busmaster(device_t dev)
200 1.1 jklos {
201 1.1 jklos adapter_t *sc = (adapter_t *)dev;
202 1.1 jklos uint32_t reg;
203 1.1 jklos
204 1.1 jklos t3_os_pci_read_config_4(sc, PCI_COMMAND_STATUS_REG, ®);
205 1.1 jklos reg |= PCI_COMMAND_MASTER_ENABLE;
206 1.1 jklos t3_os_pci_write_config_4(sc, PCI_COMMAND_STATUS_REG, reg);
207 1.1 jklos }
208