Commit 51bcb55c authored by ghaddab's avatar ghaddab
Browse files

new driver for exmimo3

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@5596 818b1a75-f10b-46b9-bf7c-635c3b92a50f
parent 03f1e6fd
CCC = gcc
KERNEL_MAIN_TYPE=$(shell echo `uname -r | cut -d. -f-2 | tr "." "_"`)
export KERNEL_MAIN_TYPE
SUBVERSION=$(shell echo `grep '^SUBLEVEL =' /usr/src/linux/Makefile | sed -e 's, ,,g' | sed -e 's/SUBLEVEL=//'`)
IS_KERNEL_SUBVERSION_GREATER_THAN_20=$(shell if [ $(SUBVERSION) -ge 20 ] ; then echo true ; fi)
EXTRA_CFLAGS = -ggdb -D__KERNEL__ -DMODULE -D_LOOSE_KERNEL_NAMES -I/lib/modules/$(shell uname -r)/build/include -I/lib/modules/$(shell uname -r)/build/include/asm/mach-default -include /lib/modules/$(shell uname -r)/build/include/linux/autoconf.h
EXTRA_CFLAGS += -I$(PWD)/../../DEFS
obj-m += openair_rf.o
openair_rf-objs += module_main.o irq.o fileops.o exmimo_fw.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
rm -rf *.o
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
echo "Hint: this may not work if /usr/src/linux is not set to currently booted kernel."
echo "Try 'make' instead."
make -C /usr/src/linux V=1 M=`pwd`
#ifndef __DEFS_H__
#define __DEFS_H__
#include <asm/io.h>
#include <asm/bitops.h>
#include <asm/uaccess.h>
#include <asm/segment.h>
#include <asm/page.h>
#include <asm/delay.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/mm.h>
#include <linux/mman.h>
#include <linux/slab.h>
//#include <linux/config.h>
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/errno.h>
#ifdef KERNEL2_6
#include <linux/slab.h>
#endif
#include "openair_device.h"
#include "linux/moduleparam.h"
/*------------------------------------------------*/
/* Prototypes */
/*------------------------------------------------*/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)
long openair_device_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
#else
int openair_device_ioctl(struct inode *inode,struct file *filp, unsigned int cmd, unsigned long arg);
#endif
int openair_device_open (struct inode *inode,struct file *filp);
int openair_device_release (struct inode *inode,struct file *filp);
int openair_device_mmap (struct file *filp, struct vm_area_struct *vma);
int exmimo_memory_alloc(int card);
int exmimo_firmware_init(int card);
int exmimo_firmware_cleanup(int card_id);
int exmimo_send_pccmd(int card_id, unsigned int cmd);
#endif
#!/bin/sh
# Re-Enumerate FPGA card
# After resetting or powering up the card or after reloading the FPGA bitstream,
# run this script to re-enumerate the PCIe device in Linux.
# You may need to change the device path. Check lspci output for this.
# You need to run this as root:
# sudo ./do_reenumerate_expressmimo.sh
# Matthias <ihmig@eurecom.fr>, 2013
rmmod openair_rf
echo 1 > /sys/bus/pci/devices/0000\:01\:00.0/remove
echo 1 > /sys/bus/pci/devices/0000\:05\:00.0/remove
echo 1 > /sys/bus/pci/rescan
insmod openair_rf.ko
rmmod openair_rf && sleep 1 ; insmod openair_rf.ko
/** exmimo_fw.c
*
* Initialization routines for
* Shared Memory management for ExMIMO and PC(kernel) data exchange
* (memory allocation, pointer management)
*
* There is now one pci_alloc_consistent for each RX and TX buffer
* and one for all structures, including pointers, printk, firmware_dump and config
*
* Authors: Matthias Ihmig <matthias.ihmig@mytum.de>, 2012, 2013
* Riadh Ghaddab <riadh.ghaddab@eurecom.fr>
* Raymond Knopp <raymond.knopp@eurecom.fr>
*
* Changelog:
* 24.01.2013: added memory management functions for bigshm, lots of cleanups
*/
#include <linux/delay.h>
#include "extern.h"
#include "defs.h"
#include "pcie_interface.h"
/*****************************************************
* Private functions within this file
*/
void mem_SetPageReserved(void *kvirt_addr, unsigned int size_pages)
{
size_t temp_size = size_pages << PAGE_SHIFT;
void *adr = kvirt_addr;
while (temp_size > 0)
{
SetPageReserved( virt_to_page(adr) );
adr += PAGE_SIZE;
temp_size -= PAGE_SIZE;
}
}
void mem_ClearPageReserved(void *kvirt_addr, unsigned int size_pages)
{
size_t temp_size = size_pages << PAGE_SHIFT;
void *adr = kvirt_addr;
while (temp_size > 0) {
ClearPageReserved( virt_to_page(adr) );
adr += PAGE_SIZE;
temp_size -= PAGE_SIZE;
}
}
// allocates big shared memory, to be used for structures, pointers, etc.
// bigshm allocs a single larger memory block for shared structures and pointers, one per card, except: ADC+DAC buffers!
// returns -1 on error, 0 on success
int bigshm_init(int card)
{
printk("[openair][module] calling pci_alloc_consistent for card %d, bigshm (size: %lu*%lu bytes)...\n", card, BIGSHM_SIZE_PAGES, PAGE_SIZE);
if ( sizeof(dma_addr_t) != 4)
printk("!!! WARNING: sizeof (dma_addr_t) = %lu! Only 32bit mode (= 4) (also: no PAE) is supported at this time!\n", sizeof(dma_addr_t));
if ( bigshm_head[card] == NULL )
bigshm_head[card] = pci_alloc_consistent( pdev[card], BIGSHM_SIZE_PAGES<<PAGE_SHIFT, &bigshm_head_phys[card] );
if (bigshm_head[card] == NULL) {
printk("[openair][MODULE][ERROR] Cannot Allocate Memory (%lu bytes) for shared data (bigshm)\n", BIGSHM_SIZE_PAGES<<PAGE_SHIFT);
return -ENOMEM;
}
else {
printk("[openair][MODULE][INFO] Bigshm at %p (phys %x)\n", bigshm_head[card], (unsigned int) bigshm_head_phys[card]);
bigshm_currentptr[card] = bigshm_head[card];
mem_SetPageReserved( bigshm_head[card], BIGSHM_SIZE_PAGES);
memset(bigshm_head[card], 0, BIGSHM_SIZE_PAGES << PAGE_SHIFT);
}
return 0;
}
// use this instead of pci_alloc_consistent to assign memory from the bigshm block
// return kernel virtual pointer and sets physical DMA address in dma_handle
void *bigshm_assign( int card, size_t size_bytes, dma_addr_t *dma_handle_ptr )
{
void *ret;
size_t size = size_bytes;
//size = (size-1) + 4 - ( (size-1) % 4); // round up to keep addresses aligned to DWs
//size = (size-1) + 16 - ( (size-1) % 16); // round up to keep addresses aligned to 4 DWs
// round up to the next 64 DW (workaround for current bug in DMA on ExMIMO2)
size = (size-1) + 256 - ( (size-1) % 256);
if ( (bigshm_currentptr[card] - bigshm_head[card]) > (BIGSHM_SIZE_PAGES<<PAGE_SHIFT) -size ) {
printk("Not enough memory in bigshm! Make BIGSHM_SIZE_PAGES bigger!\n");
return NULL;
}
*dma_handle_ptr = bigshm_head_phys[card] + ( (dma_addr_t)bigshm_currentptr[card] - (dma_addr_t)bigshm_head[card] );
ret = bigshm_currentptr[card];
bigshm_currentptr[card] = (char *)bigshm_currentptr[card] + size;
//printk("bigshm_assign: size %d, virt = %p, dma = %x, bigshm_phys=%x, _current=%p, _head=%p\n",
// size, ret, *dma_handle_ptr, bigshm_head_phys[card], bigshm_currentptr[card], bigshm_head[card]);
return ret;
}
// assign shared memory between card an PC for data exchange: interface structure with pointers,
// firmware- and printk buffers, configuration structure
// returns -1 on error, 0 on success
int exmimo_assign_shm_vars(int card_id)
{
int j;
if (p_exmimo_pci_phys[card_id] == NULL)
{
p_exmimo_pci_phys[card_id] = (exmimo_pci_interface_bot_t *) bigshm_assign( card_id,
sizeof(exmimo_pci_interface_bot_t),
&pphys_exmimo_pci_phys[card_id]);
printk("Intializing EXMIMO interface support (exmimo_pci_bot at %p, phys %x, size %lu bytes)\n",p_exmimo_pci_phys[card_id],(unsigned int)pphys_exmimo_pci_phys[card_id], sizeof(exmimo_pci_interface_bot_t));
exmimo_pci_kvirt[card_id].firmware_block_ptr = (char *) bigshm_assign( card_id,
MAX_FIRMWARE_BLOCK_SIZE_B,
(dma_addr_t*)&(p_exmimo_pci_phys[card_id]->firmware_block_ptr));
printk("firmware_code_block_ptr : %p (phys = %08x)\n", exmimo_pci_kvirt[card_id].firmware_block_ptr, p_exmimo_pci_phys[card_id]->firmware_block_ptr);
exmimo_pci_kvirt[card_id].printk_buffer_ptr = (char *) bigshm_assign( card_id,
MAX_PRINTK_BUFFER_B,
(dma_addr_t*)&(p_exmimo_pci_phys[card_id]->printk_buffer_ptr));
printk("printk_buffer_ptr : %p (phys = %08x)\n", exmimo_pci_kvirt[card_id].printk_buffer_ptr, p_exmimo_pci_phys[card_id]->printk_buffer_ptr);
exmimo_pci_kvirt[card_id].exmimo_config_ptr = (exmimo_config_t *) bigshm_assign( card_id,
sizeof(exmimo_config_t),
(dma_addr_t*)&(p_exmimo_pci_phys[card_id]->exmimo_config_ptr));
printk("exmimo_config_ptr : %p (phys = %08x)\n", exmimo_pci_kvirt[card_id].exmimo_config_ptr, p_exmimo_pci_phys[card_id]->exmimo_config_ptr);
exmimo_pci_kvirt[card_id].exmimo_id_ptr = (exmimo_id_t *) bigshm_assign( card_id,
sizeof(exmimo_id_t),
(dma_addr_t*)&(p_exmimo_pci_phys[card_id]->exmimo_id_ptr));
printk("exmimo_id_ptr : %p (phys = %08x)\n", exmimo_pci_kvirt[card_id].exmimo_id_ptr, p_exmimo_pci_phys[card_id]->exmimo_id_ptr);
if ( p_exmimo_pci_phys[card_id] == NULL || exmimo_pci_kvirt[card_id].firmware_block_ptr == NULL
|| exmimo_pci_kvirt[card_id].printk_buffer_ptr == NULL || exmimo_pci_kvirt[card_id].exmimo_config_ptr == NULL
|| exmimo_pci_kvirt[card_id].exmimo_id_ptr == NULL )
return -1;
for (j=0; j<MAX_ANTENNAS; j++)
{
// size 4*1 should be sufficient, but just to make sure we can also use DMA of size 4DW as fallback
exmimo_pci_kvirt[card_id].rxcnt_ptr[j] = (uint32_t *) bigshm_assign( card_id, 4*4,
(dma_addr_t*)&(p_exmimo_pci_phys[card_id]->rxcnt_ptr[j]) );
printk("exmimo_pci_kvirt[%d].rxcnt_ptr[%d] = %p (phys = %08x)\n", card_id, j, exmimo_pci_kvirt[card_id].rxcnt_ptr[j], p_exmimo_pci_phys[card_id]->rxcnt_ptr[j]);
exmimo_pci_kvirt[card_id].txcnt_ptr[j] = (uint32_t *) bigshm_assign( card_id, 4*4,
(dma_addr_t*)&(p_exmimo_pci_phys[card_id]->txcnt_ptr[j]) );
printk("exmimo_pci_kvirt[%d].txcnt_ptr[%d] = %p (phys = %08x)\n", card_id, j, exmimo_pci_kvirt[card_id].txcnt_ptr[j], p_exmimo_pci_phys[card_id]->txcnt_ptr[j]);
if ( exmimo_pci_kvirt[card_id].rxcnt_ptr[j] == NULL || exmimo_pci_kvirt[card_id].txcnt_ptr[j] == NULL)
return -1;
}
}
return 0;
}
// allocate memory for RX and TX chains for all antennas
// returns -1 on error, 0 on success
int exmimo_allocate_rx_tx_buffers(int card_id)
{
size_t size;
int j,i;
dma_addr_t dma_addr_dummy;
// Round up to the next PAGE_SIZE (typ. 4096 bytes)
size = (ADAC_BUFFERSZ_PERCHAN_B >> PAGE_SHIFT) + 1;
size <<= PAGE_SHIFT;
for (j=0; j<MAX_ANTENNAS; j++)
{
exmimo_pci_kvirt[card_id].adc_head[j] = (uint32_t *)pci_alloc_consistent( pdev[card_id], size, &dma_addr_dummy);
p_exmimo_pci_phys[card_id]->adc_head[j]=((uint32_t*)&dma_addr_dummy)[0];
printk("exmimo_pci_kvirt[%d].adc_head[%d] = %p (phys = %08x)\n", card_id, j, exmimo_pci_kvirt[card_id].adc_head[j], p_exmimo_pci_phys[card_id]->adc_head[j]);
if ( exmimo_pci_kvirt[card_id].adc_head[j] == NULL)
return -1;
// printk("[MODULE MAIN0]Phys address TX[0] : (%8lx)\n",p_exmimo_pci_phys[0]->dac_head[ openair_mmap_getAntTX(2) ]);
mem_SetPageReserved( exmimo_pci_kvirt[card_id].adc_head[j], size >> PAGE_SHIFT );
memset( exmimo_pci_kvirt[card_id].adc_head[j], 0x10+j, size);
// printk("[MODULE MAIN1]Phys address TX[0] : (%8lx)\n",p_exmimo_pci_phys[0]->dac_head[ openair_mmap_getAntTX(2) ]);
exmimo_pci_kvirt[card_id].dac_head[j] = (uint32_t *)pci_alloc_consistent( pdev[card_id], size,&dma_addr_dummy);
p_exmimo_pci_phys[card_id]->dac_head[j]=((uint32_t*)&dma_addr_dummy)[0];
// printk("exmimo_pci_kvirt[%d].dac_head[%d] = %p (phys = %08x)\n", card_id, j, exmimo_pci_kvirt[card_id].dac_head[j], p_exmimo_pci_phys[card_id]->dac_head[j]);
if ( exmimo_pci_kvirt[card_id].dac_head[j] == NULL)
return -ENOMEM;
// printk("[MODULE MAIN2]Phys address TX[0] : (%8lx)\n",p_exmimo_pci_phys[0]->dac_head[ openair_mmap_getAntTX(2) ]);
mem_SetPageReserved( exmimo_pci_kvirt[card_id].dac_head[j], size >> PAGE_SHIFT );
memset( exmimo_pci_kvirt[card_id].dac_head[j], 0x20+j, size);
// printk("[MODULE MAIN3]Phys address TX[0] : (%8lx)\n",p_exmimo_pci_phys[0]->dac_head[ openair_mmap_getAntTX(2) ]);
}
return 0;
}
/*********************************************
* Public functions ExpressMIMO Interface
*/
/* Allocates buffer and assigns pointers
*
* return 0 on success
*/
int exmimo_memory_alloc(int card)
{
int i;
if ( bigshm_init( card ) ) {
printk("exmimo_memory_alloc(): bigshm_init failed for card %d.\n", card);
return -ENOMEM;
}
if ( exmimo_assign_shm_vars( card ) ) {
printk("exmimo_memory_alloc(): exmimo_assign_shm_vars failed to assign enough shared memory for all variables and structures for card %i!\n", card);
return -ENOMEM;
}
if ( exmimo_allocate_rx_tx_buffers( card ) ) {
printk("exmimo_memory_alloc(): exmimo_allocate_rx_tx_buffers() failed to allocate enough memory for RX and TX buffers for card %i!\n", card);
return -ENOMEM;
}
return 0;
}
/*
* Copies pointer to Leon
*/
int exmimo_firmware_init(int card)
{
// put DMA pointer to exmimo_pci_interface_bot into LEON register
iowrite32( pphys_exmimo_pci_phys[card], (bar[card]+PCIE_PCIBASEL) ); // lower 32bit of address
iowrite32( 0, (bar[card]+PCIE_PCIBASEH) ); // higher 32bit of address
iowrite32(pphys_exmimo_pci_phys[card]-> p_exmimo_pci_phys[card_id]->adc_head[j]);
if (exmimo_pci_kvirt[card].exmimo_id_ptr->board_swrev == BOARD_SWREV_CMDREGISTERS)
iowrite32( EXMIMO_CONTROL2_COOKIE, bar[card]+ PCIE_CONTROL2);
//printk("exmimo_firmware_init(): initializing Leon (EXMIMO_PCIE_INIT)...\n");
exmimo_send_pccmd(card, EXMIMO_PCIE_INIT);
return 0;
}
/*
* Free memory on unloading the kernel driver
*/
int exmimo_firmware_cleanup(int card)
{
size_t size;
int j;
// free exmimo_allocate_rx_tx_buffers
size = (ADAC_BUFFERSZ_PERCHAN_B >> PAGE_SHIFT) + 1;
size <<= PAGE_SHIFT;
for (j=0; j<MAX_ANTENNAS; j++)
{
if ( exmimo_pci_kvirt[card].adc_head[j] ) {
mem_ClearPageReserved( exmimo_pci_kvirt[card].adc_head[j], size >> PAGE_SHIFT );
pci_free_consistent( pdev[card], size, exmimo_pci_kvirt[card].adc_head[j], p_exmimo_pci_phys[card]->adc_head[j] );
}
if ( exmimo_pci_kvirt[card].dac_head[j] ) {
mem_ClearPageReserved( exmimo_pci_kvirt[card].dac_head[j], size >> PAGE_SHIFT );
pci_free_consistent( pdev[card], size, exmimo_pci_kvirt[card].dac_head[j], p_exmimo_pci_phys[card]->dac_head[j] );
}
}
if ( bigshm_head[card] ) {
printk("free bigshm_head[%d] pdev %p, size %lu, head %p, phys %x\n", card, pdev[card], BIGSHM_SIZE_PAGES<<PAGE_SHIFT, bigshm_head[card], (unsigned int)bigshm_head_phys[card]);
mem_ClearPageReserved( bigshm_head[card], BIGSHM_SIZE_PAGES );
pci_free_consistent( pdev[card], BIGSHM_SIZE_PAGES<<PAGE_SHIFT, bigshm_head[card], bigshm_head_phys[card]);
}
return 0;
}
/*
* Send command to Leon and wait until command is completed
*/
int exmimo_send_pccmd(int card_id, unsigned int cmd)
{
unsigned int val;
unsigned int cnt=0;
//printk("Sending command to ExpressMIMO (card %d) : %x\n",card_id, cmd);
iowrite32(cmd,(bar[card_id]+PCIE_CONTROL1));
// printk("Readback of control1 %x\n",ioread32(bar[0]+PCIE_CONTROL1));
switch(cmd)
{
case EXMIMO_CONFIG :
break;
case EXMIMO_PCIE_INIT :
break;
}
// workaround for ExMIMO1&2: no command ack -> sleep
while (cnt<100 && ( ioread32(bar[card_id]+PCIE_CONTROL1) != EXMIMO_NOP )) {
//printk("ctrl0: %08x, ctrl1: %08x, ctrl2: %08x, status: %08x\n", ioread32(bar[card_id]+PCIE_CONTROL0), ioread32(bar[card_id]+PCIE_CONTROL1), ioread32(bar[card_id]+PCIE_CONTROL2), ioread32(bar[card_id]+PCIE_STATUS));
msleep(100);
cnt++;
}
if (cnt==100)
printk("exmimo_send_pccmd error: Timeout: no EXMIMO_NOP received within 10sec for card%d, pccmd=%x\n", card_id, cmd);
//printk("Ctrl0: %08x, ctrl1: %08x, ctrl2: %08x, status: %08x\n", ioread32(bar[card_id]+PCIE_CONTROL0), ioread32(bar[card_id]+PCIE_CONTROL1), ioread32(bar[card_id]+PCIE_CONTROL2), ioread32(bar[card_id]+PCIE_STATUS));
return(0);
}
#ifndef __EXTERN_H__
#define __EXTERN_H__
#include <linux/init.h>
#include <linux/module.h>
#include <linux/pci.h>
#ifdef KERNEL2_6
#include <linux/slab.h>
#endif
#include "defs.h"
#include "pcie_interface.h"
extern char number_of_cards;
extern int major;
extern struct pci_dev *pdev[MAX_CARDS];
extern void __iomem *bar[MAX_CARDS];
extern void *bigshm_head[MAX_CARDS];
extern void *bigshm_currentptr[MAX_CARDS];
extern dma_addr_t bigshm_head_phys[MAX_CARDS];
extern dma_addr_t pphys_exmimo_pci_phys[MAX_CARDS];
extern exmimo_pci_interface_bot_t *p_exmimo_pci_phys[MAX_CARDS];
extern exmimo_pci_interface_bot_virtual_t exmimo_pci_kvirt[MAX_CARDS];
#endif // __EXTERN_H__
/** fileops.c
*
* Device IOCTL File Operations on character device /dev/openair0
*
* Authors: Matthias Ihmig <matthias.ihmig@mytum.de>, 2012, 2013
* Riadh Ghaddab <riadh.ghaddab@eurecom.fr>
* Raymond Knopp <raymond.knopp@eurecom.fr>
*
* Changelog:
* 14.01.2013: removed remaining of BIGPHYS stuff and replaced with pci_alloc_consistent
*/
#include <linux/delay.h>
#include "openair_device.h"
#include "defs.h"
#include "extern.h"
#include "pcie_interface.h"
#define invert4(x) { \
unsigned int ltmp; \
ltmp=x; x=((ltmp & 0xff)<<24) | ((ltmp & 0xff00)<<8) | \
((ltmp & 0xff0000)>>8) | ((ltmp & 0xff000000)>>24); \
}
extern int get_frame_done;
int is_card_num_invalid(int card)
{
if (card<0 || card>=number_of_cards)
{
printk("[openair][IOCTL]: ERROR: received invalid card number (%d)!\n", card);
return -1;
}
else
return 0;
}
//-----------------------------------------------------------------------------
int openair_device_open (struct inode *inode,struct file *filp)
{
//printk("[openair][MODULE] openair_open()\n");
return 0;
}
//-----------------------------------------------------------------------------
int openair_device_release (struct inode *inode,struct file *filp)
{
// printk("[openair][MODULE] openair_release(), MODE = %d\n",openair_daq_vars.mode);
return 0;
}
//-----------------------------------------------------------------------------
int openair_device_mmap(struct file *filp, struct vm_area_struct *vma)
{
unsigned long phys;
unsigned long start = (unsigned long)vma->vm_start;
unsigned long size = (unsigned long)(vma->vm_end-vma->vm_start);
unsigned long maxsize;
unsigned int memblock_ind;
unsigned int card;
memblock_ind = openair_mmap_getMemBlock( vma->vm_pgoff );
card = openair_mmap_getCard( vma->vm_pgoff );
/*printk("[openair][MMAP] called (start %lx, end %lx, pg_off %lx, size %lx)\n",
vma->vm_start,
vma->vm_end,
vma->vm_pgoff,
size);
*/
vma->vm_pgoff = 0;
// not supported by 64 bit kernels
//vma->vm_flags |= VM_RESERVED;
vma->vm_flags |= VM_IO;
if ( is_card_num_invalid(card) )
return -EINVAL;
if (memblock_ind == openair_mmap_BIGSHM)
{
// map a buffer from bigshm
maxsize = BIGSHM_SIZE_PAGES<<PAGE_SHIFT;
if ( size > maxsize) {
printk("[openair][MMAP][ERROR] Trying to map more than %d bytes (req size=%d)\n",
(unsigned int)(BIGSHM_SIZE_PAGES<<PAGE_SHIFT), (unsigned int)size);
return -EINVAL;
}
phys = bigshm_head_phys[card];
}
else if ( (memblock_ind & 1) == 1)
{
// mmap a RX buffer
maxsize = ADAC_BUFFERSZ_PERCHAN_B;
if ( size > maxsize) {
printk("[openair][MMAP][ERROR] Trying to map more than %d bytes (req size=%d)\n",
(unsigned int)(ADAC_BUFFERSZ_PERCHAN_B), (unsigned int)size);
return -EINVAL;
}
phys = p_exmimo_pci_phys[card]->adc_head[ openair_mmap_getAntRX(memblock_ind) ];
}
else
{
// mmap a TX buffer
maxsize = ADAC_BUFFERSZ_PERCHAN_B;
if ( size > maxsize) {
printk("[openair][MMAP][ERROR] Trying to map more than %d bytes (%d)\n",
(unsigned int)(ADAC_BUFFERSZ_PERCHAN_B), (unsigned int)size);
return -EINVAL;
}
phys = p_exmimo_pci_phys[card]->dac_head[ openair_mmap_getAntTX(memblock_ind) ];
}
if (0)
printk("[openair][MMAP] card%d: map phys (%08lx) at start %lx, end %lx, pg_off %lx, size %lx\n",
card,