Home | History | Annotate | Line # | Download | only in cxgb
cxgb_osdep.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 
     32  1.1.2.2  uebayasi #include <sys/param.h>
     33  1.1.2.2  uebayasi #include <sys/systm.h>
     34  1.1.2.2  uebayasi #include <sys/kernel.h>
     35  1.1.2.2  uebayasi #include <sys/conf.h>
     36  1.1.2.2  uebayasi #include <machine/bus.h>
     37  1.1.2.2  uebayasi #include <sys/ioccom.h>
     38  1.1.2.2  uebayasi #include <sys/mbuf.h>
     39  1.1.2.2  uebayasi #include <sys/socket.h>
     40  1.1.2.2  uebayasi #include <sys/sockio.h>
     41  1.1.2.2  uebayasi #include <sys/sysctl.h>
     42  1.1.2.2  uebayasi #include <sys/queue.h>
     43  1.1.2.2  uebayasi 
     44  1.1.2.2  uebayasi #include <net/bpf.h>
     45  1.1.2.2  uebayasi #include <net/if.h>
     46  1.1.2.2  uebayasi #include <net/if_arp.h>
     47  1.1.2.2  uebayasi #include <net/if_dl.h>
     48  1.1.2.2  uebayasi #include <net/if_media.h>
     49  1.1.2.2  uebayasi #include <net/if_types.h>
     50  1.1.2.2  uebayasi 
     51  1.1.2.2  uebayasi #include <netinet/in_systm.h>
     52  1.1.2.2  uebayasi #include <netinet/in.h>
     53  1.1.2.2  uebayasi #include <netinet/ip.h>
     54  1.1.2.2  uebayasi #include <netinet/tcp.h>
     55  1.1.2.2  uebayasi #include <netinet/udp.h>
     56  1.1.2.2  uebayasi 
     57  1.1.2.2  uebayasi #include <dev/pci/pcireg.h>
     58  1.1.2.2  uebayasi #include <dev/pci/pcivar.h>
     59  1.1.2.2  uebayasi 
     60  1.1.2.2  uebayasi #include <dev/pci/cxgb/cxgb_include.h>
     61  1.1.2.2  uebayasi #include <altq/altq_conf.h>
     62  1.1.2.2  uebayasi 
     63  1.1.2.2  uebayasi int cxgb_initialized = FALSE;
     64  1.1.2.2  uebayasi 
     65  1.1.2.2  uebayasi int atomic_fetchadd_int(volatile int *p, int v)
     66  1.1.2.2  uebayasi {
     67  1.1.2.2  uebayasi     int tmp = *p;
     68  1.1.2.2  uebayasi     *p += v;
     69  1.1.2.2  uebayasi     return (tmp);
     70  1.1.2.2  uebayasi }
     71  1.1.2.2  uebayasi 
     72  1.1.2.2  uebayasi #if 0
     73  1.1.2.2  uebayasi int atomic_add_int(volatile int *p, int v)
     74  1.1.2.2  uebayasi {
     75  1.1.2.2  uebayasi     return (*p += v);
     76  1.1.2.2  uebayasi }
     77  1.1.2.2  uebayasi #endif
     78  1.1.2.2  uebayasi 
     79  1.1.2.2  uebayasi int atomic_load_acq_int(volatile int *p)
     80  1.1.2.2  uebayasi {
     81  1.1.2.2  uebayasi     return (*p);
     82  1.1.2.2  uebayasi }
     83  1.1.2.2  uebayasi 
     84  1.1.2.2  uebayasi void atomic_store_rel_int(volatile int *p, int v)
     85  1.1.2.2  uebayasi {
     86  1.1.2.2  uebayasi     *p = v;
     87  1.1.2.2  uebayasi }
     88  1.1.2.2  uebayasi 
     89  1.1.2.2  uebayasi u_short in_cksum_hdr(struct ip *ih)
     90  1.1.2.2  uebayasi {
     91  1.1.2.2  uebayasi 	u_long sum = 0;
     92  1.1.2.2  uebayasi 	u_short *p = (u_short *)ih;
     93  1.1.2.2  uebayasi 	int i;
     94  1.1.2.2  uebayasi 
     95  1.1.2.2  uebayasi         i = ih->ip_hl*2;
     96  1.1.2.2  uebayasi 	while (i--)
     97  1.1.2.2  uebayasi 		sum += *p++;
     98  1.1.2.2  uebayasi 
     99  1.1.2.2  uebayasi 	if (sum > 0xffff)
    100  1.1.2.2  uebayasi 		sum -= 0xffff;
    101  1.1.2.2  uebayasi 
    102  1.1.2.2  uebayasi 	return (~sum);
    103  1.1.2.2  uebayasi }
    104  1.1.2.2  uebayasi 
    105  1.1.2.2  uebayasi void m_cljset(struct mbuf *m, void *cl, int type)
    106  1.1.2.2  uebayasi {
    107  1.1.2.2  uebayasi     MEXTADD(m, cl, m->m_len, M_DEVBUF, NULL, NULL);
    108  1.1.2.2  uebayasi }
    109  1.1.2.2  uebayasi 
    110  1.1.2.2  uebayasi int
    111  1.1.2.2  uebayasi _m_explode(struct mbuf *m)
    112  1.1.2.2  uebayasi {
    113  1.1.2.2  uebayasi         int i, offset, type, first, len;
    114  1.1.2.2  uebayasi         uint8_t *cl;
    115  1.1.2.2  uebayasi         struct mbuf *m0, *head = NULL;
    116  1.1.2.2  uebayasi         struct mbuf_vec *mv;
    117  1.1.2.2  uebayasi 
    118  1.1.2.2  uebayasi #ifdef INVARIANTS
    119  1.1.2.2  uebayasi         len = m->m_len;
    120  1.1.2.2  uebayasi         m0 = m->m_next;
    121  1.1.2.2  uebayasi         while (m0) {
    122  1.1.2.2  uebayasi                 KASSERT((m0->m_flags & M_PKTHDR) == 0,
    123  1.1.2.2  uebayasi                     ("pkthdr set on intermediate mbuf - pre"));
    124  1.1.2.2  uebayasi                 len += m0->m_len;
    125  1.1.2.2  uebayasi                 m0 = m0->m_next;
    126  1.1.2.2  uebayasi 
    127  1.1.2.2  uebayasi         }
    128  1.1.2.2  uebayasi         if (len != m->m_pkthdr.len)
    129  1.1.2.2  uebayasi                 panic("at start len=%d pktlen=%d", len, m->m_pkthdr.len);
    130  1.1.2.2  uebayasi #endif
    131  1.1.2.2  uebayasi         mv = (struct mbuf_vec *)((m)->m_pktdat);
    132  1.1.2.2  uebayasi         first = mv->mv_first;
    133  1.1.2.2  uebayasi         for (i = mv->mv_count + first - 1; i > first; i--) {
    134  1.1.2.2  uebayasi                 type = mbuf_vec_get_type(mv, i);
    135  1.1.2.2  uebayasi                 cl = mv->mv_vec[i].mi_base;
    136  1.1.2.2  uebayasi                 offset = mv->mv_vec[i].mi_offset;
    137  1.1.2.2  uebayasi                 len = mv->mv_vec[i].mi_len;
    138  1.1.2.2  uebayasi #if 0
    139  1.1.2.2  uebayasi                 if (__predict_false(type == EXT_MBUF)) {
    140  1.1.2.2  uebayasi                         m0 = (struct mbuf *)cl;
    141  1.1.2.2  uebayasi                         KASSERT((m0->m_flags & M_EXT) == 0);
    142  1.1.2.2  uebayasi                         m0->m_len = len;
    143  1.1.2.2  uebayasi                         m0->m_data = cl + offset;
    144  1.1.2.2  uebayasi                         goto skip_cluster;
    145  1.1.2.2  uebayasi 
    146  1.1.2.2  uebayasi                 } else
    147  1.1.2.2  uebayasi #endif
    148  1.1.2.2  uebayasi 		if ((m0 = m_get(M_NOWAIT, MT_DATA)) == NULL) {
    149  1.1.2.2  uebayasi                         /*
    150  1.1.2.2  uebayasi                          * Check for extra memory leaks
    151  1.1.2.2  uebayasi                          */
    152  1.1.2.2  uebayasi                         m_freem(head);
    153  1.1.2.2  uebayasi                         return (ENOMEM);
    154  1.1.2.2  uebayasi                 }
    155  1.1.2.2  uebayasi                 m0->m_flags = 0;
    156  1.1.2.2  uebayasi 
    157  1.1.2.2  uebayasi                 m0->m_len = mv->mv_vec[i].mi_len;
    158  1.1.2.2  uebayasi                 m_cljset(m0, (uint8_t *)cl, type);
    159  1.1.2.2  uebayasi                 if (offset)
    160  1.1.2.2  uebayasi                         m_adj(m0, offset);
    161  1.1.2.2  uebayasi //        skip_cluster:
    162  1.1.2.2  uebayasi                 m0->m_next = head;
    163  1.1.2.2  uebayasi                 m->m_len -= m0->m_len;
    164  1.1.2.2  uebayasi                 head = m0;
    165  1.1.2.2  uebayasi         }
    166  1.1.2.2  uebayasi         offset = mv->mv_vec[first].mi_offset;
    167  1.1.2.2  uebayasi         cl = mv->mv_vec[first].mi_base;
    168  1.1.2.2  uebayasi         type = mbuf_vec_get_type(mv, first);
    169  1.1.2.2  uebayasi         m->m_flags &= ~(M_IOVEC);
    170  1.1.2.2  uebayasi         m_cljset(m, cl, type);
    171  1.1.2.2  uebayasi         if (offset)
    172  1.1.2.2  uebayasi                 m_adj(m, offset);
    173  1.1.2.2  uebayasi         m->m_next = head;
    174  1.1.2.2  uebayasi         head = m;
    175  1.1.2.2  uebayasi         M_SANITY(m, 0);
    176  1.1.2.2  uebayasi 
    177  1.1.2.2  uebayasi         return (0);
    178  1.1.2.2  uebayasi }
    179  1.1.2.2  uebayasi 
    180  1.1.2.2  uebayasi /*
    181  1.1.2.2  uebayasi  * Allocate a chunk of memory using kmalloc or, if that fails, vmalloc.
    182  1.1.2.2  uebayasi  * The allocated memory is cleared.
    183  1.1.2.2  uebayasi  */
    184  1.1.2.2  uebayasi void *
    185  1.1.2.2  uebayasi cxgb_alloc_mem(unsigned long size)
    186  1.1.2.2  uebayasi {
    187  1.1.2.2  uebayasi     return malloc(size, M_DEVBUF, M_ZERO);
    188  1.1.2.2  uebayasi }
    189  1.1.2.2  uebayasi 
    190  1.1.2.2  uebayasi /*
    191  1.1.2.2  uebayasi  * Free memory allocated through t3_alloc_mem().
    192  1.1.2.2  uebayasi  */
    193  1.1.2.2  uebayasi void
    194  1.1.2.2  uebayasi cxgb_free_mem(void *addr)
    195  1.1.2.2  uebayasi {
    196  1.1.2.2  uebayasi     free(addr, M_DEVBUF);
    197  1.1.2.2  uebayasi }
    198  1.1.2.2  uebayasi 
    199  1.1.2.2  uebayasi void pci_enable_busmaster(device_t dev)
    200  1.1.2.2  uebayasi {
    201  1.1.2.2  uebayasi     adapter_t *sc = (adapter_t *)dev;
    202  1.1.2.2  uebayasi     uint32_t reg;
    203  1.1.2.2  uebayasi 
    204  1.1.2.2  uebayasi     t3_os_pci_read_config_4(sc, PCI_COMMAND_STATUS_REG, &reg);
    205  1.1.2.2  uebayasi     reg |= PCI_COMMAND_MASTER_ENABLE;
    206  1.1.2.2  uebayasi     t3_os_pci_write_config_4(sc, PCI_COMMAND_STATUS_REG, reg);
    207  1.1.2.2  uebayasi }
    208