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 }