/* * CFE OS Independent Layer * * Copyright 2007, Broadcom Corporation * All Rights Reserved. * * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. * * $Id: cfe_osl.c,v 1.1.1.1 2008/07/21 09:20:53 james26_jang Exp $ */ #include #include #include osl_t * osl_attach(void *pdev) { osl_t *osh; osh = (osl_t *)KMALLOC(sizeof(osl_t), 0); ASSERT(osh); bzero(osh, sizeof(osl_t)); osh->pdev = pdev; return osh; } void osl_detach(osl_t *osh) { if (osh == NULL) return; KFREE((void*) KERNADDR(PHYSADDR((ulong)osh))); } struct lbuf * osl_pktget(uint len) { uchar *buf; struct lbuf *lb; ASSERT(len <= LBDATASZ); if (!(buf = KMALLOC(LBUFSZ, 0))) return NULL; lb = (struct lbuf *) &buf[LBDATASZ]; bzero(lb, sizeof(struct lbuf)); lb->head = lb->data = buf; lb->end = buf + len; lb->len = len; lb->tail = lb->data + len; return lb; } void osl_pktfree(osl_t *osh, struct lbuf *lb, bool send) { struct lbuf *next; if (send && osh->tx_fn) osh->tx_fn(osh->tx_ctx, lb, 0); for (; lb; lb = next) { ASSERT(!lb->link); next = lb->next; KFREE((void *) KERNADDR(PHYSADDR((ulong) lb->head))); } } struct lbuf * osl_pktdup(struct lbuf *lb) { struct lbuf *dup; if (!(dup = osl_pktget(lb->len))) return NULL; bcopy(lb->data, dup->data, lb->len); ASSERT(!lb->link); return dup; } void osl_pktsetlen(struct lbuf *lb, uint len) { ASSERT((lb->data + len) <= lb->end); lb->len = len; lb->tail = lb->data + len; } uchar * osl_pktpush(struct lbuf *lb, uint bytes) { ASSERT((lb->data - bytes) >= lb->head); lb->data -= bytes; lb->len += bytes; return lb->data; } uchar * osl_pktpull(struct lbuf *lb, uint bytes) { ASSERT((lb->data + bytes) <= lb->end); ASSERT(lb->len >= bytes); lb->data += bytes; lb->len -= bytes; return lb->data; } void * osl_dma_alloc_consistent(uint size, ulong *pap) { void *buf; if (!(buf = KMALLOC(size, DMA_CONSISTENT_ALIGN))) return NULL; *((ulong *) pap) = PHYSADDR((ulong) buf); cfe_flushcache(CFE_CACHE_FLUSH_D); return (void *) UNCADDR((ulong) buf); } void osl_dma_free_consistent(void *va) { KFREE((void *) KERNADDR(PHYSADDR((ulong) va))); } #ifdef BCMDBG_ASSERT void osl_assert(char *exp, char *file, int line) { printf("assertion \"%s\" failed: file \"%s\", line %d\n", exp, file, line); *((int *) 0) = 0; } #endif /* BCMDBG_ASSERT */ int osl_busprobe(uint32 *val, uint32 addr) { *val = R_REG(NULL, (volatile uint32 *) addr); return 0; } /* translate bcmerros */ int osl_error(int bcmerror) { if (bcmerror) return -1; else return 0; } /* Converts a OS packet to driver packet. * The original packet data is copied to the new driver packet */ void osl_pkt_frmnative(iocb_buffer_t *buffer, struct lbuf *lb) { bcopy(buffer->buf_ptr, PKTDATA(NULL, lb), buffer->buf_length); } /* Converts a driver packet into OS packet. * The data is copied to the OS packet */ void osl_pkt_tonative(struct lbuf* lb, iocb_buffer_t *buffer) { bcopy(PKTDATA(NULL, lb), buffer->buf_ptr, PKTLEN(NULL, lb)); buffer->buf_retlen = PKTLEN(NULL, lb); /* RFC894: Minimum length of IP over Ethernet packet is 46 octets */ if (buffer->buf_retlen < 60) { bzero(buffer->buf_ptr + buffer->buf_retlen, 60 - buffer->buf_retlen); buffer->buf_retlen = 60; } }