1/* 2 * CFE OS Independent Layer 3 * 4 * Copyright (C) 2015, Broadcom Corporation. All Rights Reserved. 5 * 6 * Permission to use, copy, modify, and/or distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 13 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 15 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 16 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 * 18 * $Id: cfe_osl.c 419467 2013-08-21 09:19:48Z $ 19 */ 20 21#include <typedefs.h> 22#include <bcmdefs.h> 23#include <osl.h> 24#include <bcmutils.h> 25 26/* Global ASSERT type */ 27uint32 g_assert_type = 0; 28 29osl_t * 30osl_attach(void *pdev) 31{ 32 osl_t *osh; 33 34 osh = (osl_t *)KMALLOC(sizeof(osl_t), 0); 35 ASSERT(osh); 36 37 bzero(osh, sizeof(osl_t)); 38 osh->pdev = pdev; 39 return osh; 40} 41 42void 43osl_detach(osl_t *osh) 44{ 45 if (osh == NULL) 46 return; 47 KFREE((void*) KERNADDR(PHYSADDR((ulong)osh))); 48} 49 50struct lbuf * 51osl_pktget(uint len) 52{ 53 uchar *buf; 54 struct lbuf *lb; 55 56 ASSERT(len <= LBDATASZ); 57 58 if (!(buf = KMALLOC(LBUFSZ, 0))) 59 return NULL; 60 61 lb = (struct lbuf *) &buf[LBDATASZ]; 62 bzero(lb, sizeof(struct lbuf)); 63 lb->head = lb->data = buf; 64 lb->end = buf + len; 65 lb->len = len; 66 lb->tail = lb->data + len; 67 return lb; 68} 69 70void 71osl_pktfree(osl_t *osh, struct lbuf *lb, bool send) 72{ 73 struct lbuf *next; 74 75 if (send && osh->tx_fn) 76 osh->tx_fn(osh->tx_ctx, lb, 0); 77 78 for (; lb; lb = next) { 79 ASSERT(!lb->link); 80 next = lb->next; 81 KFREE((void *) KERNADDR(PHYSADDR((ulong) lb->head))); 82 } 83} 84 85struct lbuf * 86osl_pktdup(struct lbuf *lb) 87{ 88 struct lbuf *dup; 89 90 if (!(dup = osl_pktget(lb->len))) 91 return NULL; 92 93 bcopy(lb->data, dup->data, lb->len); 94 ASSERT(!lb->link); 95 return dup; 96} 97 98void 99osl_pktsetlen(struct lbuf *lb, uint len) 100{ 101 ASSERT((lb->data + len) <= lb->end); 102 103 lb->len = len; 104 lb->tail = lb->data + len; 105} 106 107uchar * 108osl_pktpush(struct lbuf *lb, uint bytes) 109{ 110 ASSERT((lb->data - bytes) >= lb->head); 111 112 lb->data -= bytes; 113 lb->len += bytes; 114 115 return lb->data; 116} 117 118uchar * 119osl_pktpull(struct lbuf *lb, uint bytes) 120{ 121 ASSERT((lb->data + bytes) <= lb->end); 122 ASSERT(lb->len >= bytes); 123 124 lb->data += bytes; 125 lb->len -= bytes; 126 127 return lb->data; 128} 129 130void * 131osl_dma_alloc_consistent(uint size, uint16 align_bits, uint *alloced, ulong *pap) 132{ 133 void *buf; 134 uint16 align = (1 << align_bits); 135 136 /* fix up the alignment requirements first */ 137 if (!ISALIGNED(DMA_CONSISTENT_ALIGN, align)) 138 size += align; 139 *alloced = size; 140 141 if (!(buf = KMALLOC(size, DMA_CONSISTENT_ALIGN))) 142 return NULL; 143 144 *((ulong *) pap) = PHYSADDR((ulong) buf); 145 146 cfe_flushcache(CFE_CACHE_FLUSH_D); 147 148 return (void *) UNCADDR((ulong) buf); 149} 150 151void 152osl_dma_free_consistent(void *va) 153{ 154 KFREE((void *) KERNADDR(PHYSADDR((ulong) va))); 155} 156 157 158int 159osl_busprobe(uint32 *val, uint32 addr) 160{ 161 *val = R_REG(NULL, (volatile uint32 *) addr); 162 163 return 0; 164} 165 166/* translate bcmerros */ 167int 168osl_error(int bcmerror) 169{ 170 if (bcmerror) 171 return -1; 172 else 173 return 0; 174} 175 176/* Converts a OS packet to driver packet. 177 * The original packet data is copied to the new driver packet 178 */ 179void 180osl_pkt_frmnative(iocb_buffer_t *buffer, struct lbuf *lb) 181{ 182 bcopy(buffer->buf_ptr, PKTDATA(NULL, lb), buffer->buf_length); 183} 184 185/* Converts a driver packet into OS packet. 186 * The data is copied to the OS packet 187 */ 188void 189osl_pkt_tonative(struct lbuf* lb, iocb_buffer_t *buffer) 190{ 191 bcopy(PKTDATA(NULL, lb), buffer->buf_ptr, PKTLEN(NULL, lb)); 192 buffer->buf_retlen = PKTLEN(NULL, lb); 193 194 /* RFC894: Minimum length of IP over Ethernet packet is 46 octets */ 195 if (buffer->buf_retlen < 60) { 196 bzero(buffer->buf_ptr + buffer->buf_retlen, 60 - buffer->buf_retlen); 197 buffer->buf_retlen = 60; 198 } 199} 200