1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2009-2012 Emulex. All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 
  28 
  29 /*
  30  * Source file containing the implementation of the driver
  31  * helper functions
  32  */
  33 
  34 #include <oce_impl.h>
  35 
  36 /*
  37  * function to breakup a block of memory into pages and return the address
  38  * in an array
  39  *
  40  * dbuf - pointer to structure describing DMA-able memory
  41  * pa_list - [OUT] pointer to an array to return the PA of pages
  42  * list_size - number of entries in pa_list
  43  */
  44 void
  45 oce_page_list(oce_dma_buf_t *dbuf,
  46     struct phys_addr *pa_list, int list_size)
  47 {
  48         int i = 0;
  49         uint64_t paddr = 0;
  50 
  51         ASSERT(dbuf != NULL);
  52         ASSERT(pa_list != NULL);
  53 
  54         paddr = DBUF_PA(*dbuf);
  55         for (i = 0; i < list_size; i++) {
  56                 pa_list[i].lo = ADDR_LO(paddr);
  57                 pa_list[i].hi = ADDR_HI(paddr);
  58                 paddr += PAGE_4K;
  59         }
  60 } /* oce_page_list */
  61 
  62 void
  63 oce_gen_hkey(char *hkey, int key_size)
  64 {
  65         int i;
  66         int nkeys = key_size/sizeof (uint32_t);
  67         for (i = 0; i < nkeys; i++) {
  68                 (void) random_get_pseudo_bytes(
  69                     (uint8_t *)&hkey[i * sizeof (uint32_t)],
  70                     sizeof (uint32_t));
  71         }
  72 }
  73 
  74 int
  75 oce_atomic_reserve(uint32_t *count_p, uint32_t n)
  76 {
  77         uint32_t oldval;
  78         uint32_t newval;
  79 
  80         /*
  81          * ATOMICALLY
  82          */
  83         do {
  84                 oldval = *count_p;
  85                 if (oldval < n)
  86                         return (-1);
  87                 newval = oldval - n;
  88 
  89         } while (atomic_cas_32(count_p, oldval, newval) != oldval);
  90 
  91         return (newval);
  92 }
  93 
  94 
  95 /*
  96  * function to insert vtag to packet
  97  *
  98  * mp - mblk pointer
  99  * vlan_tag - tag to be inserted
 100  *
 101  * return none
 102  */
 103 void
 104 oce_insert_vtag(mblk_t *mp, uint16_t vlan_tag)
 105 {
 106         struct ether_vlan_header  *evh;
 107         (void) memmove(mp->b_rptr - VTAG_SIZE,
 108             mp->b_rptr, 2 * ETHERADDRL);
 109         mp->b_rptr -= VTAG_SIZE;
 110         evh = (struct ether_vlan_header *)(void *)mp->b_rptr;
 111         evh->ether_tpid = htons(VLAN_TPID);
 112         evh->ether_tci = htons(vlan_tag);
 113 }
 114 
 115 /*
 116  * function to strip  vtag from packet
 117  *
 118  * mp - mblk pointer
 119  *
 120  * return none
 121  */
 122 
 123 void
 124 oce_remove_vtag(mblk_t *mp)
 125 {
 126         (void) memmove(mp->b_rptr + VTAG_SIZE, mp->b_rptr,
 127             ETHERADDRL * 2);
 128         mp->b_rptr += VTAG_SIZE;
 129 }