Home | History | Annotate | Line # | Download | only in cxgb
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, &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