Commit e47829af authored by Raymond Knopp's avatar Raymond Knopp

removal of EXPRESS MIMO HW drivers/libraries, same for mobipass.

parent 17eb5eed
......@@ -522,7 +522,7 @@ add_library(F1AP
add_list1_option(NB_ANTENNAS_RX "2" "Number of antennas in reception" "1" "2" "4")
add_list1_option(NB_ANTENNAS_TX "4" "Number of antennas in transmission" "1" "2" "4")
add_list2_option(RF_BOARD "EXMIMO" "RF head type" "None" "EXMIMO" "OAI_USRP" "OAI_BLADERF" "CPRIGW" "OAI_LMSSDR" "OAI_SIMU")
add_list2_option(RF_BOARD "RF head type" "None" "OAI_USRP" "OAI_BLADERF" "CPRIGW" "OAI_LMSSDR" "OAI_SIMU")
add_list2_option(TRANSP_PRO "None" "Transport protocol type" "None" "ETHERNET")
......@@ -547,15 +547,6 @@ set (SHLIB_LOADER_SOURCES
# include RF devices / transport protocols library modules
######################################################################
include_directories("${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/")
include_directories ("${OPENAIR_TARGETS}/ARCH/EXMIMO/DEFS/")
#set (option_HWEXMIMOLIB_lib "-l ")
set(HWLIB_EXMIMO_SOURCE
${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c
# ${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/gain_control.c
)
add_library(oai_exmimodevif MODULE ${HWLIB_EXMIMO_SOURCE} )
include_directories("${OPENAIR_TARGETS}/ARCH/USRP/USERSPACE/LIB/")
set(HWLIB_USRP_SOURCE
${OPENAIR_TARGETS}/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
......@@ -596,20 +587,6 @@ add_library(oai_irisdevif MODULE ${HWLIB_IRIS_SOURCE})
target_include_directories(oai_irisdevif PRIVATE /usr/local/lib/SoapySDR/modules0.7/)
target_link_libraries(oai_irisdevif SoapySDR)
include_directories("${OPENAIR_TARGETS}/ARCH/mobipass/")
set(TPLIB_MOBIPASS_SOURCE
${OPENAIR_TARGETS}/ARCH/mobipass/interface.c
${OPENAIR_TARGETS}/ARCH/mobipass/mobipass.c
${OPENAIR_TARGETS}/ARCH/mobipass/queues.c
)
add_library(oai_mobipass MODULE ${TPLIB_MOBIPASS_SOURCE} )
# Hide all functions/variables in the mobipass library.
# Use __attribute__((__visibility__("default")))
# in the source code to unhide a function/variable.
get_target_property(mobipas_cflags oai_mobipass COMPILE_FLAGS)
set_target_properties(oai_mobipass PROPERTIES COMPILE_FLAGS "${mobipass_cflags} -fvisibility=hidden")
# TCP bridge libraries
######################################################################
......@@ -819,8 +796,6 @@ include_directories("${OPENAIR3_DIR}/UDP")
include_directories("${OPENAIR3_DIR}/GTPV1-U")
include_directories("${OPENAIR_DIR}/targets/COMMON")
include_directories("${OPENAIR_DIR}/targets/ARCH/COMMON")
include_directories("${OPENAIR_DIR}/targets/ARCH/EXMIMO/USERSPACE/LIB/")
include_directories("${OPENAIR_DIR}/targets/ARCH/EXMIMO/DEFS")
include_directories("${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/PHY")
include_directories("${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/MAC")
include_directories("${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/RRC")
......@@ -1875,10 +1850,6 @@ ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/bypass_session_layer.c
#${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/emu_transport.c
)
add_library(OPENAIR0_LIB
${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c
)
include_directories("${NFAPI_DIR}/nfapi/public_inc")
include_directories("${NFAPI_DIR}/common/public_inc")
include_directories("${NFAPI_DIR}/pnf/public_inc")
......@@ -2452,14 +2423,6 @@ if(OAI_NW_DRIVER_USE_NETLINK)
endif()
make_driver(oai_nw_drv ${OPENAIR2_DIR}/NETWORK_DRIVER/LTE ${oai_nw_drv_src})
# Exmimo board drivers
#########################
list(APPEND openair_rf_src module_main.c irq.c fileops.c exmimo_fw.c)
make_driver(openair_rf ${OPENAIR_TARGETS}/ARCH/EXMIMO/DRIVER/eurecom ${openair_rf_src})
add_executable(updatefw
${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/OAI_FW_INIT/updatefw.c
)
# ue_ip: purpose ???
###############
......@@ -2470,22 +2433,6 @@ endif()
make_driver(ue_ip ${OPENAIR2_DIR}/NETWORK_DRIVER/UE_IP ${ue_ip_src})
# OCTAVE tools
###############
set(OCT_INCL -I${OPENAIR_TARGETS}/ARCH/EXMIMO/DEFS -I${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB -I${OPENAIR_TARGETS}/ARCH/COMMON)
set(OCT_LIBS -L${CMAKE_CURRENT_BINARY_DIR} -lm -lOPENAIR0_LIB)
set(OCT_FLAGS -DEXMIMO)
set(OCT_DIR ${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/OCTAVE)
set(OCT_FILES
oarf_config_exmimo.oct
oarf_config_exmimo.oct
oarf_get_frame.oct
oarf_stop.oct
oarf_send_frame.oct
oarf_get_num_detected_cards.oct
oarf_stop_without_reset.oct
)
foreach(file IN ITEMS ${OCT_FILES})
string(REGEX REPLACE "oct *$" "cc" src ${file})
add_custom_command(
......
......@@ -110,7 +110,7 @@ Options
Rel8 limits the implementation to 3GPP Release 8 version
Rel10 limits the implementation to 3GPP Release 10 version
-w | --hardware
EXMIMO, USRP, BLADERF, ETHERNET, LMSSDR, IRIS, None (Default)
USRP, BLADERF, ETHERNET, LMSSDR, IRIS, None (Default)
Adds this RF board support (in external packages installation and in compilation)
-t | --transport protocol
ETHERNET , None
......@@ -173,10 +173,9 @@ Options
Generate virtual RF driver
to use it, set the environement variable RFSIMULATOR to \"enb\" in the eNB and to the eNB IP address in the UEs
Usage (first build):
NI/ETTUS B201 + COTS UE : ./build_oai -I --eNB -x --install-system-files -w USRP
NI/ETTUS B210 + COTS UE : ./build_oai -I --eNB -x --install-system-files -w USRP
Usage (Regular):
Eurecom EXMIMO + OAI ENB : ./build_oai --eNB -x
NI/ETTUS B201 + OAI ENB : ./build_oai --eNB -x -w USRP"
NI/ETTUS B210 + OAI ENB : ./build_oai --eNB -x -w USRP"
}
......@@ -241,9 +240,6 @@ function main() {
-w | --hardware)
# Use OAI_USRP as the key word USRP is used inside UHD driver
case "$2" in
"EXMIMO")
HW="EXMIMO"
;;
"USRP" | "BLADERF" | "LMSSDR" | "IRIS" | "SIMU")
HW="OAI_"$2
;;
......@@ -398,7 +394,7 @@ function main() {
if [ "$eNB" = "1" ] ; then
if [ "$HW" = "None" -a "$TP" = "None" ] ; then
echo_fatal "Define a local radio head (e.g. -w EXMIMO) or a transport protocol (e.g. -t ETHERNET) to communicate with a remote radio head!"
echo_fatal "Define a local radio head (e.g. -w USRP) or a transport protocol (e.g. -t ETHERNET) to communicate with a remote radio head!"
fi
if [ "$HW" = "None" ] ; then
echo_info "No radio head has been selected (HW set to $HW)"
......@@ -411,14 +407,7 @@ function main() {
echo_info "RF HW set to $HW"
# If the user doesn't specify the Linux scheduler to use, we set a value
if [ "$DEADLINE_SCHEDULER_FLAG_USER" = "" ]; then
case "$HW" in
"EXMIMO")
DEADLINE_SCHEDULER_FLAG_USER="True"
;;
*)
DEADLINE_SCHEDULER_FLAG_USER="False"
;;
esac
fi
#Disable CPU Affinity for deadline scheduler
if [ "$DEADLINE_SCHEDULER_FLAG_USER" = "True" ] ; then
......@@ -517,7 +506,7 @@ function main() {
config_libconfig_shlib=params_libconfig
# first generate the CMakefile in the right directory
if [ "$eNB" = "1" -o "$UE" = "1" -o "$HW" = "EXMIMO" ] ; then
if [ "$eNB" = "1" -o "$UE" = "1" ] ; then
# LTE softmodem compilation
[ "$CLEAN" = "1" ] && rm -rf $DIR/$lte_build_dir/build
......@@ -687,28 +676,6 @@ function main() {
done
fi
# EXMIMO drivers & firmware loader
###############
if [ "$HW" = "EXMIMO" ] ; then
echo_info "Compiling Express MIMO 2 board drivers"
compilations \
$lte_build_dir openair_rf \
CMakeFiles/openair_rf/openair_rf.ko $dbin/openair_rf.ko
compilations \
$lte_build_dir updatefw \
updatefw $dbin/updatefw
echo_info "Compiling oarf tools. The logfile for compilation is here: $dlog/oarf.txt"
make -C $OPENAIR_DIR/cmake_targets/$lte_build_dir/build oarf > $dlog/oarf.txt 2>&1
cp $OPENAIR_DIR/cmake_targets/$lte_build_dir/build/*.oct $dbin
if [ -s $dbin/oarf_config_exmimo.oct ] ; then
echo_success "oarf tools compiled"
else
echo_error "oarf tools compilation failed"
fi
cp $OPENAIR_DIR/cmake_targets/tools/init_exmimo2 $dbin
fi
# Telnet server compilation
#####################
if [ "$BUILD_TELNETSRV" = "1" ] ; then
......@@ -735,15 +702,7 @@ function main() {
rm -f $dbin/liboai_device.so
# link liboai_device.so with the selected RF device library
if [ "$HW" == "EXMIMO" ] ; then
compilations \
$lte_build_dir oai_exmimodevif \
liboai_exmimodevif.so $dbin/liboai_exmimodevif.so.$REL
ln -sf liboai_exmimodevif.so liboai_device.so
ln -sf $dbin/liboai_exmimodevif.so.$REL $dbin/liboai_device.so
echo_info "liboai_device.so is linked to EXMIMO device library"
elif [ "$HW" == "OAI_USRP" ] ; then
if [ "$HW" == "OAI_USRP" ] ; then
compilations \
$lte_build_dir oai_usrpdevif \
liboai_usrpdevif.so $dbin/liboai_usrpdevif.so.$REL
......
# PROMGEN: Xilinx Prom Generator O.76xd
# Copyright (c) 1995-2011 Xilinx, Inc. All rights reserved.
SOFTWARE_VERSION O.76xd
DATE 1/ 3/2017 - 11:49
SOURCE /homes/kaltenbe/Devel/openair/openairinterface5g/targets/ARCH/EXMIMO/BITSTREAM/exmimo2_prom.mcs
DEVICE 8192K
DATA_WIDTH 4
FILL_DATA 0xFF
SIGNATURE 0x416AB633
START_ADDRESS 0x00000000 END_ADDRESS 0x00406577 DIRECTION_UP "express-mimo2.bit" 6slx150tfgg900
This diff is collapsed.
PROMGEN: Xilinx Prom Generator O.76xd
Copyright (c) 1995-2011 Xilinx, Inc. All rights reserved.
promgen -w -p mcs -c FF -o /homes/kaltenbe/Devel/openair/openairinterface5g/targets/ARCH/EXMIMO/BITSTREAM//exmimo2_prom -s 8192 -u 0000 express-mimo2.bit -spi
PROM /homes/kaltenbe/Devel/openair/openairinterface5g/targets/ARCH/EXMIMO/BITSTREAM/exmimo2_prom.prm map: Tue Jan 3 11:49:20 2017
Calculating PROM checksum with fill value ff
Format Mcs86 (32-bit)
Size 8192K
PROM start 0000:0000
PROM end 007f:ffff
PROM checksum 416ab633
Addr1 Addr2 Date File(s)
0000:0000 0040:6577 Jan 3 10:48:16 2017 express-mimo2.bit
setMode -bs
setCable -port auto
Identify
identifyMPM
assignFile -p 1 -file "express-mimo2.bit"
Program -p 1 -defaultVersion 0
quit
#!/bin/bash
impact -batch prom_generate.cmd
impact -batch prom_load.cmd
setMode -pff
addConfigDevice -name "exmimo2_prom"
setSubmode -pffspi
setAttribute -configdevice -attr multibootBpiType -value ""
addDesign -version 0 -name "0"
setMode -pff
addDeviceChain -index 0
setMode -pff
addDeviceChain -index 0
setAttribute -configdevice -attr compressed -value "FALSE"
setAttribute -configdevice -attr compressed -value "FALSE"
setAttribute -configdevice -attr autoSize -value "FALSE"
setAttribute -configdevice -attr fileFormat -value "mcs"
setAttribute -configdevice -attr fillValue -value "FF"
setAttribute -configdevice -attr swapBit -value "FALSE"
setAttribute -configdevice -attr dir -value "UP"
setAttribute -configdevice -attr multiboot -value "FALSE"
setAttribute -configdevice -attr multiboot -value "FALSE"
setAttribute -configdevice -attr spiSelected -value "TRUE"
setAttribute -configdevice -attr spiSelected -value "TRUE"
addPromDevice -p 1 -size 8192 -name 8M
setMode -pff
addDeviceChain -index 0
setMode -pff
addDeviceChain -index 0
setSubmode -pffspi
setMode -pff
setAttribute -design -attr name -value "0000"
addDevice -p 1 -file "express-mimo2.bit"
setMode -pff
setSubmode -pffspi
generate
setCurrentDesign -version 0
quit
setMode -bs
setCable -port auto
Identify -inferir
identifyMPM
assignFile -p 1 -file "express-mimo2.bit"
attachflash -position 1 -spi "W25Q64BV"
assignfiletoattachedflash -position 1 -file "exmimo2_prom.mcs"
attachflash -position 1 -spi "W25Q64BV"
Program -p 1 -dataWidth 4 -spionly -e -v -loadfpga
quit
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef OPENAIR_DEVICE_H
#define OPENAIR_DEVICE_H
// Maximum number of concurrently supported cards
#define MAX_CARDS 16
#define INIT_ZEROS {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
/** PCIe subsystem configuration Space
*/
// Vendor and System IDs
//
#define XILINX_VENDOR 0x10ee
#define XILINX_ID 0x0007
//
// PCIe Subsystem Vendor ID
#define EURECOM_VENDOR 0x0001
#define TELECOM_PARISTECH_VENDOR 0x0002
/*
PCIe Subsystem ID = exmimo_id.board_exmimoversion(1,2) (4 bits) | exmimo_id.board_hwrev (4 bits) | exmimo_id.board_swrev (Protocol Revision, 8 bits)
Board IDs (exmimo_id.board_exmimoversion(1,2) (4 bits) + exmimo_id.board_hwrev (4 bits))
0x11 => ExpressMIMO-1, first run/HW revision
0x12 => ExpressMIMO-1, second run
0x21 => ExpressMIMO-2, first run
0x22 => ExpressMIMO-2, second run
SW/Protocol revisions: (exmimo_id.board_swrev (Protocol Revision, 8 bits)
BOARD_SWREV_LEGACY:
- IRQ Leon->PC Bit 7 (AHBPCIE_INTERRUPT_ASSERT_BIT) must be cleared in PC kernel driver
- PC->Leon and Leon->PC commands share a single register CONTROL1
BOARD_SWREV_CMDREGISTERS:
- IRQ Leon->PC Bit 7 (AHBPCIE_INTERRUPT_ASSERT_BIT) is automatically cleared on PCIe read
- PC->Leon and Leon->PC commands have separete command registers CONTROL1 (PC->Leon) and CONTROL2 (Leon->PC)
BOARD_SWREV_CMDFIFOS:
- uses two command FIFOs (for PC->Leon and Leon->PC), by Telecom Paristech
*/
#define BOARD_SWREV_LEGACY 0x07
#define BOARD_SWREV_CMDREGISTERS 0x08
#define BOARD_SWREV_CNTL2 0x0A
#define BOARD_SWREV_CMDFIFOS 0x11
// ExpressMIMO PCIe register offsets to bar0
//
#define PCIE_CONTROL0 0x00
#define PCIE_CONTROL1 0x04
#define PCIE_CONTROL2 0x64
#define PCIE_STATUS 0x08
#define PCIE_PCIBASEL 0x1c
#define PCIE_PCIBASEH 0x20
// Device IO definitions and operations
//
#define openair_MAJOR 127
//#define openair_writel(dev,offset,val) pci_write_config_dword(dev,(int)offset,(unsigned int)val)//{writel((uclong)(val),(ulong)(port)); mb();}
//#define openair_readl(dev,offset,val) pci_read_config_dword(dev,(int)offset,(unsigned int*)val)//{writel((uclong)(val),(ulong)(port)); mb();}
#define openair_IOC_MAGIC 'm'
#define openair_GET_BIGSHMTOPS_KVIRT _IOR(openair_IOC_MAGIC,1,int)
#define openair_GET_PCI_INTERFACE_BOTS_KVIRT _IOR(openair_IOC_MAGIC,2,int)
#define openair_GET_NUM_DETECTED_CARDS _IOR(openair_IOC_MAGIC,3,int)
#define openair_DUMP_CONFIG _IOR(openair_IOC_MAGIC,18,int)
#define openair_GET_FRAME _IOR(openair_IOC_MAGIC,6,int)
#define openair_START_RT_ACQUISITION _IOR(openair_IOC_MAGIC,28,int)
#define openair_STOP _IOR(openair_IOC_MAGIC,5,int)
#define openair_STOP_WITHOUT_RESET _IOR(openair_IOC_MAGIC,9,int)
#define openair_RECONFIGURE _IOR(openair_IOC_MAGIC,10,int)
#define openair_UPDATE_FIRMWARE _IOR(openair_IOC_MAGIC,40,int)
/* Update firmware commands */
#define UPDATE_FIRMWARE_TRANSFER_BLOCK 0x1
#define UPDATE_FIRMWARE_CLEAR_BSS 0x2
#define UPDATE_FIRMWARE_START_EXECUTION 0x3
#define UPDATE_FIRMWARE_FORCE_REBOOT 0x4
#define UPDATE_FIRMWARE_TEST_GOK 0x5
// mmap page offset vg_pgoff is used to pass arguments to kernel
// bit0..3: memory block: BIGSHM:0, RX:1,3,5,7, TX:2,4,6,8
// bit4..7: card_id
#define openair_mmap_BIGSHM 0
#define openair_mmap_RX(ant) (((ant)<<1)+1)
#define openair_mmap_TX(ant) (((ant)<<1)+2)
#define openair_mmap_getMemBlock(o) ((o)&0xF)
#define openair_mmap_getAntRX(o) (((o)-1)>>1)
#define openair_mmap_getAntTX(o) (((o)-2)>>1)
#define openair_mmap_Card(c) ( ((c)&0xF)<<4 )
#define openair_mmap_getCard(o) ( ((o)>>4)&0xF )
#endif /* OPENAIR_DEVICE_H */
This diff is collapsed.
CCC = gcc
include $(OPENAIR_DIR)/common/utils/Makefile.inc
KERNEL_MAIN_TYPE:=$(shell echo `uname -r | cut -d. -f-2 | tr "." "_"`)
export KERNEL_MAIN_TYPE
EXTRA_CFLAGS = -ggdb -D__KERNEL__ -DMODULE -D_LOOSE_KERNEL_NAMES -I$(KERNEL_DIR)/build/include -I$(KERNEL_DIR)/build/include/asm/mach-default -include $(KERNEL_DIR)/build/include/linux/autoconf.h
EXTRA_CFLAGS += -I$(PWD)/../../DEFS
ccflags-y= $(CFLAGS) $(EXTRA_CFLAGS)
CFLAGS=
obj-m += openair_rf.o
openair_rf-objs += module_main.o irq.o fileops.o exmimo_fw.o
all:
make -C $(KERNEL_DIR)/build M=$(PWD) modules
clean:
rm -rf *.o
make -C $(KERNEL_DIR)/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`
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#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
This diff is collapsed.
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#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__
This diff is collapsed.
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/** irq.c
- IRQ Handler: IRQ from Leon to PCIe/Kernel: exmimo_irq_handler
- sends received packets to userspace
- send command from PC to Leon and trigger IRQ on Leon using CONTROL1 register
- commands are defined in $OPENAIR0/express-mimo/software/pcie_interface.h
- added: pass card_id as parameter to tasklet and irq handler
Authors:
Raymond Knopp <raymond.knopp@eurecom.fr>
Matthias Ihmig <matthias.ihmig@mytum.de>, 2011, 2013
*/
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/kthread.h>
#include <linux/sched.h>
#include <linux/swab.h>
#include "openair_device.h"
#include "extern.h"
unsigned int openair_bh_cnt;
int get_frame_done = 0;
void pcie_printk(int card_id);
void openair_do_tasklet (unsigned long card_id);
DECLARE_TASKLET (openair_tasklet, openair_do_tasklet, 0);
irqreturn_t openair_irq_handler(int irq, void *cookie)
{
unsigned int irqval;
unsigned int irqcmd = EXMIMO_NOP;
unsigned long card_id; // = (unsigned long) cookie;
unsigned int pcie_control = PCIE_CONTROL2;
// check interrupt status register
//pci_read_config_word(pdev[0],6 , &irqval);
// find card_id. cookie is set by request_irq and static, so we will always find it
for (card_id=0; card_id<MAX_CARDS; card_id++)
if ( pdev[card_id] == cookie )
break;
if (exmimo_pci_kvirt[card_id].exmimo_id_ptr->board_swrev == BOARD_SWREV_LEGACY)
pcie_control = PCIE_CONTROL1;
else
pcie_control = PCIE_CONTROL2;
//printk("irq hndl called: card_id=%i, irqval=%i\n", card_id, irqval);
// get AHBPCIE interrupt line (bit 7) to determine if IRQ was for us from ExMIMO card, or from a different device
// reading CONTROL0 will also clear this bit and the LEON-to-PC IRQ line
irqval = ioread32(bar[card_id]+PCIE_CONTROL0);
irqcmd = ioread32(bar[card_id]+pcie_control);
//printk("IRQ handler: ctrl0: %08x, ctrl1: %08x, ctrl2: %08x, status: %08x\n", irqval, ioread32(bar[card_id]+PCIE_CONTROL1), ioread32(bar[card_id]+PCIE_CONTROL2), ioread32(bar[card_id]+PCIE_STATUS));
if ( (irqval & 0x80) == 0 ) { // CTRL0.bit7 is no set -> IRQ is not from ExMIMO i.e. not for us
if (exmimo_pci_kvirt[card_id].exmimo_id_ptr->board_swrev == BOARD_SWREV_CMDREGISTERS) {
if (irqcmd != EXMIMO_NOP && irqcmd != EXMIMO_CONTROL2_COOKIE) {
if (irqcmd == GET_FRAME_DONE) {
get_frame_done = 1;
}
openair_tasklet.data = card_id;
tasklet_schedule(&openair_tasklet);
openair_bh_cnt++;
return IRQ_HANDLED;
} else {
return IRQ_NONE;
}
} else
return IRQ_NONE;
} else {
if (exmimo_pci_kvirt[card_id].exmimo_id_ptr->board_swrev == BOARD_SWREV_LEGACY) {
// clear PCIE interrupt (bit 7 of register 0x0)
iowrite32(irqval&0xffffff7f,bar[card_id]+PCIE_CONTROL0);
}
if (irqcmd == GET_FRAME_DONE) {
get_frame_done = 1;
}
openair_tasklet.data = card_id;
tasklet_schedule(&openair_tasklet);
openair_bh_cnt++;
return IRQ_HANDLED;
}
}
void openair_do_tasklet (unsigned long card_id)
{
int save_irq_cnt = openair_bh_cnt;
unsigned int irqcmd;
unsigned int pcie_control = PCIE_CONTROL2;
openair_bh_cnt = 0;
if (exmimo_pci_kvirt[card_id].exmimo_id_ptr->board_swrev == BOARD_SWREV_LEGACY)
pcie_control = PCIE_CONTROL1;
else
pcie_control = PCIE_CONTROL2;
irqcmd = ioread32(bar[card_id]+pcie_control);
if (save_irq_cnt > 1)
printk("[openair][IRQ tasklet(%ld)]: Warning: received more than 1 PCIE IRQ (openair_bh_cnt=%i), only the last one is acted upon(irqcmd= %i (0x%X)\n", card_id, openair_bh_cnt, irqcmd, irqcmd);
switch( irqcmd ) {
case PCI_PRINTK:
// printk("Got PCIe interrupt for printk ...\n");
pcie_printk((int) card_id);
break;
case GET_FRAME_DONE:
printk("[openair][IRQ tasklet] : Got PCIe interrupt for GET_FRAME_DONE ...\n");
break;
case EXMIMO_NOP:
printk("[openair][IRQ tasklet] : Received IRQ, with CONTROL0.bit7(IRQ Leon2PC) set, but irqcmd = EXMIMO_NOP. This should not happen with bitstreams built after June 3rd 2013.\n");
break;
default:
printk("[openair][IRQ tasklet] : Got unknown PCIe cmd: card_id = %li, irqcmd(CONTROL1) = %i (0x%X)\n", card_id, irqcmd, irqcmd);
}
iowrite32(EXMIMO_NOP, bar[card_id]+pcie_control);
}
void pcie_printk(int card_id)
{
char *buffer = exmimo_pci_kvirt[card_id].printk_buffer_ptr;
unsigned int len = ((unsigned int *)buffer)[0];
unsigned int off=0,i;
unsigned char *dword;
unsigned char tmp;
//printk("In pci_fifo_printk : buffer %p, len %d: \n",buffer,len);
printk("[LEON card%d]: ", card_id);
if (len<1024) {
if ( (len&3) >0 )
off=1;
for (i=0; i<(off+(len>>2)); i++) {
dword = &((unsigned char *)buffer)[(1+i)<<2];
tmp = dword[3];
dword[3] = dword[0];
dword[0] = tmp;
tmp = dword[2];
dword[2] = dword[1];
dword[1] = tmp;
}
for (i=0; i<len; i++)
printk("%c",((char*)&buffer[4])[i]);
}
}
This diff is collapsed.
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef __VARS_H__
#define __VARS_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"
unsigned int openair_irq_enabled[MAX_CARDS] = INIT_ZEROS;
unsigned int openair_chrdev_registered = 0;
unsigned int openair_pci_device_enabled[MAX_CARDS] = INIT_ZEROS;
struct pci_dev *pdev[MAX_CARDS] = INIT_ZEROS;
void __iomem *bar[MAX_CARDS] = INIT_ZEROS;
resource_size_t mmio_start[MAX_CARDS] = INIT_ZEROS;
resource_size_t mmio_length[MAX_CARDS];
unsigned int mmio_flags[MAX_CARDS];
int major;
char number_of_cards;
// bigshm allocs a single larger block, used for shared structures and pointers
dma_addr_t bigshm_head_phys[MAX_CARDS] = INIT_ZEROS;
void *bigshm_head[MAX_CARDS] = INIT_ZEROS;
void *bigshm_currentptr[MAX_CARDS];
dma_addr_t pphys_exmimo_pci_phys[MAX_CARDS]; // phys pointer to pci_bot structure in shared mem
exmimo_pci_interface_bot_t *p_exmimo_pci_phys[MAX_CARDS] = INIT_ZEROS; // inside struct has physical (DMA) pointers to pci_bot memory blocks
exmimo_pci_interface_bot_virtual_t exmimo_pci_kvirt[MAX_CARDS]; // has virtual pointers to pci_bot memory blocks
#endif
CCC = gcc
include $(OPENAIR_DIR)/common/utils/Makefile.inc
KERNEL_MAIN_TYPE=$(shell echo `uname -r | cut -d. -f-2 | tr "." "_"`)
export KERNEL_MAIN_TYPE
EXTRA_CFLAGS = -ggdb -D__KERNEL__ -DMODULE -D_LOOSE_KERNEL_NAMES -I$(KERNEL_DIR)/build/include -I$(KERNEL_DIR)/build/include/asm/mach-default -include $(KERNEL_DIR)/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 $(KERNEL_DIR)/build M=$(PWD) modules
clean:
rm -rf *.o
make -C $(KERNEL_DIR)/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`
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#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
This diff is collapsed.
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#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__
This diff is collapsed.
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/** irq.c
- IRQ Handler: IRQ from Leon to PCIe/Kernel: exmimo_irq_handler
- sends received packets to userspace
- send command from PC to Leon and trigger IRQ on Leon using CONTROL1 register
- commands are defined in $OPENAIR0/express-mimo/software/pcie_interface.h
- added: pass card_id as parameter to tasklet and irq handler
Authors:
Raymond Knopp <raymond.knopp@eurecom.fr>
Matthias Ihmig <matthias.ihmig@mytum.de>, 2011, 2013
*/
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/kthread.h>
#include <linux/sched.h>
#include <linux/swab.h>
#include "openair_device.h"
#include "extern.h"
unsigned int openair_bh_cnt;
int get_frame_done = 0;
void pcie_printk(int card_id);
void openair_do_tasklet (unsigned long card_id);
DECLARE_TASKLET (openair_tasklet, openair_do_tasklet, 0);
irqreturn_t openair_irq_handler(int irq, void *cookie)
{
unsigned int irqval;
unsigned int irqcmd = EXMIMO_NOP;
unsigned long card_id; // = (unsigned long) cookie;
unsigned int pcie_control = PCIE_CONTROL2;
// check interrupt status register
//pci_read_config_word(pdev[0],6 , &irqval);
// find card_id. cookie is set by request_irq and static, so we will always find it
for (card_id=0; card_id<MAX_CARDS; card_id++)
if ( pdev[card_id] == cookie )
break;
if (exmimo_pci_kvirt[card_id].exmimo_id_ptr->board_swrev == BOARD_SWREV_LEGACY)
pcie_control = PCIE_CONTROL1;
else
pcie_control = PCIE_CONTROL2;
//printk("irq hndl called: card_id=%i, irqval=%i\n", card_id, irqval);
// get AHBPCIE interrupt line (bit 7) to determine if IRQ was for us from ExMIMO card, or from a different device
// reading CONTROL0 will also clear this bit and the LEON-to-PC IRQ line
irqval = ioread32(bar[card_id]+PCIE_CONTROL0);
irqcmd = ioread32(bar[card_id]+pcie_control);
//printk("IRQ handler: ctrl0: %08x, ctrl1: %08x, ctrl2: %08x, status: %08x\n", irqval, ioread32(bar[card_id]+PCIE_CONTROL1), ioread32(bar[card_id]+PCIE_CONTROL2), ioread32(bar[card_id]+PCIE_STATUS));
if ( (irqval & 0x80) == 0 ) { // CTRL0.bit7 is no set -> IRQ is not from ExMIMO i.e. not for us
if (exmimo_pci_kvirt[card_id].exmimo_id_ptr->board_swrev == BOARD_SWREV_CMDREGISTERS) {
if (irqcmd != EXMIMO_NOP && irqcmd != EXMIMO_CONTROL2_COOKIE) {
if (irqcmd == GET_FRAME_DONE) {
get_frame_done = 1;
}
openair_tasklet.data = card_id;
tasklet_schedule(&openair_tasklet);
openair_bh_cnt++;
return IRQ_HANDLED;
} else {
return IRQ_NONE;
}
} else
return IRQ_NONE;
} else {
if (exmimo_pci_kvirt[card_id].exmimo_id_ptr->board_swrev == BOARD_SWREV_LEGACY) {
// clear PCIE interrupt (bit 7 of register 0x0)
iowrite32(irqval&0xffffff7f,bar[card_id]+PCIE_CONTROL0);
}
if (irqcmd == GET_FRAME_DONE) {
get_frame_done = 1;
}
openair_tasklet.data = card_id;
tasklet_schedule(&openair_tasklet);
openair_bh_cnt++;
return IRQ_HANDLED;
}
}
void openair_do_tasklet (unsigned long card_id)
{
int save_irq_cnt = openair_bh_cnt;
unsigned int irqcmd;
unsigned int pcie_control = PCIE_CONTROL2;
openair_bh_cnt = 0;
if (exmimo_pci_kvirt[card_id].exmimo_id_ptr->board_swrev == BOARD_SWREV_LEGACY)
pcie_control = PCIE_CONTROL1;
else
pcie_control = PCIE_CONTROL2;
irqcmd = ioread32(bar[card_id]+pcie_control);
if (save_irq_cnt > 1)
printk("[openair][IRQ tasklet(%ld)]: Warning: received more than 1 PCIE IRQ (openair_bh_cnt=%i), only the last one is acted upon(irqcmd= %i (0x%X)\n", card_id, openair_bh_cnt, irqcmd, irqcmd);
switch( irqcmd ) {
case PCI_PRINTK:
// printk("Got PCIe interrupt for printk ...\n");
pcie_printk((int) card_id);
break;
case GET_FRAME_DONE:
printk("[openair][IRQ tasklet] : Got PCIe interrupt for GET_FRAME_DONE ...\n");
break;
case EXMIMO_NOP:
printk("[openair][IRQ tasklet] : Received IRQ, with CONTROL0.bit7(IRQ Leon2PC) set, but irqcmd = EXMIMO_NOP. This should not happen with bitstreams built after June 3rd 2013.\n");
break;
default:
printk("[openair][IRQ tasklet] : Got unknown PCIe cmd: card_id = %li, irqcmd(CONTROL1) = %i (0x%X)\n", card_id, irqcmd, irqcmd);
}
iowrite32(EXMIMO_NOP, bar[card_id]+pcie_control);
}
void pcie_printk(int card_id)
{
char *buffer = exmimo_pci_kvirt[card_id].printk_buffer_ptr;
unsigned int len = ((unsigned int *)buffer)[0];
unsigned int off=0,i;
unsigned char *dword;
unsigned char tmp;
//printk("In pci_fifo_printk : buffer %p, len %d: \n",buffer,len);
printk("[LEON card%d]: ", card_id);
if (len<1024) {
if ( (len&3) >0 )
off=1;
for (i=0; i<(off+(len>>2)); i++) {
dword = &((unsigned char *)buffer)[(1+i)<<2];
tmp = dword[3];
dword[3] = dword[0];
dword[0] = tmp;
tmp = dword[2];
dword[2] = dword[1];
dword[1] = tmp;
}
for (i=0; i<len; i++)
printk("%c",((char*)&buffer[4])[i]);
}
}
This diff is collapsed.
#!/bin/bash
PCI=`lspci -m | grep Xilinx`
if [ -z "$PCI" ]; then
echo "No card found. Stopping!"
return
fi
SLOT_NUMBER=`echo $PCI | awk -F\" '{print $1}'`
setpci -s $SLOT_NUMBER 60.b=10
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef __VARS_H__
#define __VARS_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"
unsigned int openair_irq_enabled[MAX_CARDS] = INIT_ZEROS;
unsigned int openair_chrdev_registered = 0;
unsigned int openair_pci_device_enabled[MAX_CARDS] = INIT_ZEROS;
struct pci_dev *pdev[MAX_CARDS] = INIT_ZEROS;
void __iomem *bar[MAX_CARDS] = INIT_ZEROS;
resource_size_t mmio_start[MAX_CARDS] = INIT_ZEROS;
resource_size_t mmio_length[MAX_CARDS];
unsigned int mmio_flags[MAX_CARDS];
int major;
char number_of_cards;
// bigshm allocs a single larger block, used for shared structures and pointers
dma_addr_t bigshm_head_phys[MAX_CARDS] = INIT_ZEROS;
void *bigshm_head[MAX_CARDS] = INIT_ZEROS;
void *bigshm_currentptr[MAX_CARDS];
dma_addr_t pphys_exmimo_pci_phys[MAX_CARDS]; // phys pointer to pci_bot structure in shared mem
exmimo_pci_interface_bot_t *p_exmimo_pci_phys[MAX_CARDS] = INIT_ZEROS; // inside struct has physical (DMA) pointers to pci_bot memory blocks
exmimo_pci_interface_bot_virtual_t exmimo_pci_kvirt[MAX_CARDS]; // has virtual pointers to pci_bot memory blocks
#endif
Here are the PC kernel drivers.
Currently, there are two drivers:
telecomparistech/
---
- supports the new ExpressMIMO-1 bitstream by Telecom Paristech
- uses command two command FIFOs to pass commands between Leon<->PC
eurecom/
---
- supports the legacy ExpressMIMO-1 bitstream
- supports ExpressMIMO-2, also multiple cards for sample-synchronous acquisition
- uses CONTROLx registers to pass commands between Leon<->PC
- allocates buffers in kernel space using pci_alloc_consistent
- used by ../USERSPACE/LIB/openair0_lib for simple access through userspace
obj-m += em1.o
em1-objs = em1_drv.o em1_fifos.o em1_rw.o em1_dev.o em1_ioctl.o em1_mmap.o
default:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "em1_drv.h"
static irqreturn_t irq_handler(int irq, void *dev_id)
{
uint32_t irqval;
irqreturn_t res = IRQ_NONE;
struct em1_private_s *pv = dev_id;
spin_lock(&pv->lock);
irqval = ioread32(pv->base + REG_ISTATUS);
if (irqval & IRQ_MSK) {
// printk(KERN_DEBUG "em1 irqval 0x%x", irqval);
if ((irqval & EM1_NOTFULL_IRQ) && (pv->busy & EM1_BUSY_FIFO_W)) {
wake_up_all(&pv->rq_wait_fifo_w);
res = IRQ_HANDLED;
}
if ((irqval & EM1_NOTEMPTY_IRQ) && (pv->busy & EM1_BUSY_FIFO_R)) {
wake_up_all(&pv->rq_wait_fifo_r);
res = IRQ_HANDLED;
}
if (irqval & EM1_DMA_IRQ) {
pv->dma_done = irqval >> 16;
wake_up_all(&pv->rq_wait_dma);
res = IRQ_HANDLED;
}
}
spin_unlock(&pv->lock);
return res;
}
int __devinit em1_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
int ret, i;
resource_size_t len, start;
struct em1_private_s *pv;
for (i = 0; i < MAX_EM1_DEVICES; i++)
if (em1_devices[i] == NULL)
goto found;
printk("exmimo1 : Too many devices");
return -ENOENT;
found:
pv = kmalloc(sizeof(struct em1_private_s), GFP_KERNEL);
em1_devices[i] = pv;
if (pv == NULL) {
printk(KERN_ERR "exmimo1 : Out of memory\n");
return -ENOMEM;
}
pci_set_drvdata(dev, pv);
ret = pci_enable_device(dev);
if (ret <0) {
printk(KERN_WARNING "exmimo1 : Problem when enabling PCI device\n");
goto err_kfree;
}
/* Set interrupt handler function */
ret = request_irq(dev->irq, &irq_handler, IRQF_SHARED, "exmimo1", pv);
if (ret <0) {
printk(KERN_WARNING "exmimo1 : Problem when requesting interrupt for PCI device\n");
goto err_disable;
}
/* Address of first PCI BAR region */
len = pci_resource_len(dev, 0);
start = pci_resource_start(dev, 0);
printk("exmimo1 : len : %d\n", len);
printk("exmimo1 : start : %x\n", start);
if (check_mem_region(start, len) < 0) {
printk(KERN_ERR "exmimo1 : Cannot check memory region 0, already in use\n");
ret = -ENOMEM;
goto err_req_irq;
}
if (request_mem_region(start, len, "exmimo") == NULL) {
printk(KERN_ERR "exmimo1 : Cannot get memory region 0, already in use\n");
ret = -ENOMEM;
goto err_req_irq;
}
pv->base = pci_iomap(dev, 0, len);
printk(KERN_DEBUG "exmimo1 : base address := 0x%x\n", (unsigned int)pv->base);
pci_set_master(dev);
init_waitqueue_head(&pv->rq_wait_fifo_r);
init_waitqueue_head(&pv->rq_wait_fifo_w);
init_waitqueue_head(&pv->rq_wait_dma);
pv->ie = 0;
pv->busy = 0;
pv->fifo_read_left = 0;
pv->fifo_write_left = 0;
spin_lock_init(&pv->lock);
pv->dev = &dev->dev;
pv->pdev = dev;
/* Get DMA done counter */
pv->dma_started = pv->dma_done = ioread32(pv->base + REG_ISTATUS) >> 16;
/* Disable interrupt */
iowrite32(pv->ie, pv->base + REG_FSTATUS);
return 0;
err_req_irq:
free_irq(dev->irq, pv);
err_disable:
pci_disable_device(dev);
err_kfree:
kfree(pv);
em1_devices[i] = NULL;
return ret;
}
void __devexit em1_remove(struct pci_dev *dev)
{
int i;
struct em1_private_s *pv = pci_get_drvdata(dev);
resource_size_t len, start;
printk(KERN_DEBUG "exmimo1 : remove()\n");
iounmap((void*)pv->base);
/* Address of first PCI BAR region */
len = pci_resource_len(dev, 0);
start = pci_resource_start(dev, 0);
release_mem_region(start, len);
// Unregister interrupt
free_irq(dev->irq, pv);
pci_disable_device(dev);
//Free private data
kfree(pv);
for (i = 0; i < MAX_EM1_DEVICES; i++)
if (em1_devices[i] == pv)
em1_devices[i] = NULL;
}
/*
* Local Variables:
* c-file-style: "linux"
* indent-tabs-mode: t
* tab-width: 8
* End:
*/
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "em1_drv.h"
MODULE_AUTHOR("Alexandre Becoulet, Cerdan Sebastien");
MODULE_DESCRIPTION("Driver for Express-Mimo 1 board");
MODULE_SUPPORTED_DEVICE("Express-Mimo 1");
MODULE_LICENSE("GPL");
static int major = 256;
struct em1_private_s *em1_devices[MAX_EM1_DEVICES] = {};
int em1_user_op_enter(struct em1_private_s *pv, wait_queue_t *wait,
wait_queue_head_t *wh, int busy_flag, int new_state)
{
add_wait_queue(wh, wait);
spin_lock_irq(&pv->lock);
/* wait for other tasks to leave */
while (pv->busy & busy_flag) {
if (new_state == TASK_INTERRUPTIBLE &&
signal_pending(current))
return 1;
set_current_state(new_state);
spin_unlock_irq(&pv->lock);
schedule();
spin_lock_irq(&pv->lock);
}
pv->busy |= busy_flag;
return 0;
}
void em1_user_op_leave(struct em1_private_s *pv, wait_queue_t *wait,
wait_queue_head_t *wh)
{
set_current_state(TASK_RUNNING);
spin_unlock_irq(&pv->lock);
remove_wait_queue(wh, wait);
// wake other waiting tasks
wake_up_all(wh);
}
static int em1_open(struct inode *inode, struct file *file)
{
int i;
//FIXME Lock list access
for (i = 0; i < MAX_EM1_DEVICES; i++) {
struct em1_private_s *pv = em1_devices[i];
if (pv != NULL && i == iminor(inode)) {
struct em1_file_s *fpv = kmalloc(sizeof(struct em1_file_s), GFP_KERNEL);
if (!fpv)
return -ENOMEM;
printk(KERN_DEBUG "exmimo1 : open()\n");
fpv->pv = pv;
file->private_data = fpv;
fpv->read.addr = 0;
fpv->write.addr = 0;
memset(fpv->mmap_list, 0, sizeof(fpv->mmap_list));
return 0;
}
}
return -ENODEV;
}
static int em1_release(struct inode *inode, struct file *file)
{
int i;
struct em1_file_s *fpv = file->private_data;
em1_unlock_user_page(&fpv->read);
em1_unlock_user_page(&fpv->write);
for (i = 0; i < MAX_EM1_MMAP; i++)
if (fpv->mmap_list[i].virt) {
struct em1_mmap_ctx * mctx = fpv->mmap_list + i;
pci_free_consistent(fpv->pv->pdev, mctx->size, mctx->virt, mctx->phys);
}
kfree(fpv);
printk(KERN_DEBUG "exmimo1 : release()\n");
return 0;
}
static const struct file_operations em1_fops = {
.read = em1_read,
.write = em1_write,
.open = em1_open,
.release = em1_release,
.ioctl = em1_ioctl,
.mmap = em1_mmap,
};
/* Supported devices */
static struct pci_device_id em1_pci_tbl[] = {
{ XILINX_VENDOR, XILINX_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{0,}
};
MODULE_DEVICE_TABLE(pci, em1_pci_tbl);
static struct pci_driver em1_driver = {
.name = "exmimo1",
.id_table = em1_pci_tbl,
.probe = em1_probe,
.remove = em1_remove,
};
static int __init em1_init(void)
{
int ret;
printk(KERN_DEBUG "exmimo1 : Hello world!\n");
ret = pci_register_driver(&em1_driver);
if (ret < 0) {
printk(KERN_ERR "exmimo1 : Error when registering PCI driver\n");
goto err;
}
ret = register_chrdev(major, "exmimo1", &em1_fops);
if (ret < 0) {
printk(KERN_ERR "exmimo1 : Error when registering char device\n");
goto err;
}
err:
return ret;
}
static void __exit em1_cleanup(void)
{
printk(KERN_DEBUG "exmimo1 : Goodbye world!\n");
unregister_chrdev(major, "exmimo1");
pci_unregister_driver(&em1_driver);
}
module_init(em1_init);
module_exit(em1_cleanup);
/*
* Local Variables:
* c-file-style: "linux"
* indent-tabs-mode: t
* tab-width: 8
* End:
*/
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef USER_APP
#include <linux/uaccess.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/list.h>
#include <linux/pci.h>
#include <linux/blkdev.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/spinlock_types.h>
#include <linux/interrupt.h>
/*
Operations:
- DMA from pc to em1: The Linux driver writes a 4 words command to
the control fifo [0x103 phys_hi phys_lo size] and waits for a DMA
end interrupt from the em1 board.
This operation is requested by the user application using the
write syscall. The buffer provided by the application must not
span across multiple pages.
- DMA from em1 to pc: The Linux driver writes a 4 words command to
the control fifo [0x203 phys_hi phys_lo size] and waits for a DMA
end interrupt from the em1 board.
This operation is requested by the user application using the read
syscall. The buffer provided by the application must not span
across multiple pages.
*/
#define XILINX_VENDOR 0x10ee
#define XILINX_ID 0x0007
#define REG_FCMD 0x0
#define REG_FSTATUS 0x4
#define REG_ISTATUS 0x8
#define REG_STATUS 0x10
#define REG_PCI_BASE_L 0x28
#define REG_PCI_BASE_H 0x2c
#define PUSH_FULL_STATUS_MSK (1 << 3)
#define POP_EMPTY_STATUS_MSK (1 << 2)
#define EM1_NOTFULL_IRQ (1 << 0)
#define EM1_NOTEMPTY_IRQ (1 << 1)
#define EM1_DMA_IRQ (1 << 2)
#define PUSH_NO_FULL_IRQ_MSK (1 << 19)
#define POP_NO_EMPTY_IRQ_MSK (1 << 18)
#define IRQ_MSK 7
#define EM1_CMD_OP_DMA_PC2EM1 0x0100
#define EM1_CMD_OP_DMA_EM12PC 0x0200
#define MAX_EM1_DEVICES 8
#define MAX_EM1_MMAP 4
#define EM1_BUSY_FIFO_R 1
#define EM1_BUSY_FIFO_W 2
#define EM1_BUSY_DMA 4
struct em1_private_s;
struct em1_page_s {
uintptr_t addr;
struct page *page;
};
struct em1_mmap_ctx {
void* virt;
dma_addr_t phys;
size_t size;
};
struct em1_file_s {
struct em1_private_s *pv;
struct em1_page_s read;
struct em1_page_s write;
struct em1_mmap_ctx mmap_list[MAX_EM1_MMAP];
};
struct em1_private_s {
struct pci_dev *pdev;
struct device *dev;
spinlock_t lock;
/* memeory mapped device base address */
void * base;
/* wait queues */
wait_queue_head_t rq_wait_fifo_r;
wait_queue_head_t rq_wait_fifo_w;
wait_queue_head_t rq_wait_dma;
/* Number of fifo words left to read or write */
size_t fifo_read_left;
size_t fifo_write_left;
/* Cached interrupt enabled value */
uint32_t ie;
/* Driver busy operations flags */
int busy;
/* Completed DMA transfer counters */
uint16_t dma_started, dma_done;
};
extern struct em1_private_s *em1_devices[MAX_EM1_DEVICES];
/* em1_drv.c */
int em1_user_op_enter(struct em1_private_s *pv, wait_queue_t *wait,
wait_queue_head_t *wh, int busy_flag, int new_state);
void em1_user_op_leave(struct em1_private_s *pv, wait_queue_t *wait,
wait_queue_head_t *wh);
/* em1_rw.c: read and write syscalls */
int em1_lock_user_page(struct em1_page_s *ep, uintptr_t addr, int direction);
void em1_unlock_user_page(struct em1_page_s *fpv);
ssize_t em1_write(struct file *file, const char __user *buf, size_t size, loff_t *ppos);
ssize_t em1_read(struct file *file, char __user *buf, size_t size, loff_t *ppos);
/* em1_dev.c */
int __devinit em1_probe(struct pci_dev *dev, const struct pci_device_id *id);
void __devexit em1_remove(struct pci_dev *dev);
/* em1_fifos.c */
int em1_fifo_write(struct em1_private_s *pv, const uint32_t *buf, size_t count);
int em1_fifo_read(struct em1_private_s *pv, uint32_t *buf, size_t count);
/* em1_ioctl.c */
int em1_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg);
/* em1_mmap.c */
int em1_mmap(struct file *filp, struct vm_area_struct *vma);
#endif
enum em1_ioctl_cmd {
EM1_IOCTL_FIFO_WRITE,
EM1_IOCTL_FIFO_READ,
};
#define EM1_MAX_FIFO_PAYLOAD 128
struct em1_ioctl_fifo_params {
uint32_t *words;
size_t count;
};
/*
* Local Variables:
* c-file-style: "linux"
* indent-tabs-mode: t
* tab-width: 8
* End:
*/
#!/bin/sh
sudo insmod em1.ko
sudo mknod /dev/exmimo1 c 256 0
sudo chmod 666 /dev/exmimo1
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "em1_drv.h"
int em1_fifo_write(struct em1_private_s *pv, const uint32_t *buf, size_t count)
{
int retval = 0;
size_t cnt = count;
while (cnt > 0) {
//read fifo state register
uint32_t data = ioread32(pv->base + REG_FSTATUS);
if (data & PUSH_FULL_STATUS_MSK) {
/* Enable push fifo no full interrupt */
pv->ie |= PUSH_NO_FULL_IRQ_MSK;
iowrite32(pv->ie, pv->base + REG_FSTATUS);
set_current_state(TASK_UNINTERRUPTIBLE);
spin_unlock_irq(&pv->lock);
// printk(KERN_DEBUG "sleep %08x %i", data, current->state);
schedule();
// printk(KERN_DEBUG "wake");
spin_lock_irq(&pv->lock);
continue;
}
data = *buf++;
cnt--;
iowrite32(data, pv->base + REG_FCMD);
if (!pv->fifo_write_left) {
/* Size must be retrieved from POP fifo entry */
pv->fifo_write_left = data & 0xFF;
} else {
pv->fifo_write_left--;
}
if (!pv->fifo_write_left)
break;
}
pv->ie &= ~PUSH_NO_FULL_IRQ_MSK;
iowrite32(pv->ie, pv->base + REG_FSTATUS);
return retval;
}
int em1_fifo_read(struct em1_private_s *pv, uint32_t *buf, size_t count)
{
int retval = 0;
size_t cnt = count;
while (cnt > 0) {
//read fifo state register
uint32_t data = ioread32(pv->base + REG_FSTATUS);
if (data & POP_EMPTY_STATUS_MSK) {
/* Enable pop fifo no empty interrupt */
pv->ie |= POP_NO_EMPTY_IRQ_MSK;
iowrite32(pv->ie, pv->base + REG_FSTATUS);
set_current_state(TASK_UNINTERRUPTIBLE);
spin_unlock_irq(&pv->lock);
schedule();
spin_lock_irq(&pv->lock);
continue;
}
data = ioread32(pv->base + REG_FCMD);
*buf++ = data;
cnt--;
if (!pv->fifo_read_left) {
/* Size must be retrieved from POP fifo entry */
pv->fifo_read_left = data & 0xFF;
} else {
pv->fifo_read_left--;
}
if (!pv->fifo_read_left)
break;
}
pv->ie &= ~POP_NO_EMPTY_IRQ_MSK;
iowrite32(pv->ie, pv->base + REG_FSTATUS);
return retval;
}
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "em1_drv.h"
static int em1_ioctl_fifo_write(struct em1_private_s *pv, size_t size, uint32_t *words)
{
DECLARE_WAITQUEUE(wait, current);
int res = -ERESTARTSYS;
if (!em1_user_op_enter(pv, &wait, &pv->rq_wait_fifo_w,
EM1_BUSY_FIFO_W, TASK_INTERRUPTIBLE)) {
res = em1_fifo_write(pv, words, size);
res = 0;
pv->busy &= ~EM1_BUSY_FIFO_W;
}
em1_user_op_leave(pv, &wait, &pv->rq_wait_fifo_w);
return res;
}
static int em1_ioctl_fifo_read(struct em1_private_s *pv, size_t size, uint32_t *words)
{
DECLARE_WAITQUEUE(wait, current);
int res = -ERESTARTSYS;
if (!em1_user_op_enter(pv, &wait, &pv->rq_wait_fifo_r,
EM1_BUSY_FIFO_R, TASK_INTERRUPTIBLE)) {
res = em1_fifo_read(pv, words, size);
pv->busy &= ~EM1_BUSY_FIFO_R;
}
em1_user_op_leave(pv, &wait, &pv->rq_wait_fifo_r);
return res;
}
int em1_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
struct em1_file_s *fpv = file->private_data;
struct em1_private_s *pv = fpv->pv;
switch ((enum em1_ioctl_cmd)cmd) {
case EM1_IOCTL_FIFO_WRITE: {
struct em1_ioctl_fifo_params p;
uint32_t w[EM1_MAX_FIFO_PAYLOAD];
if (copy_from_user(&p, (void*)arg, sizeof(p)))
return -EFAULT;
if (p.count > EM1_MAX_FIFO_PAYLOAD)
return -EINVAL;
if (copy_from_user(w, p.words, p.count * sizeof(uint32_t)))
return -EFAULT;
return em1_ioctl_fifo_write(pv, p.count, w);
}
case EM1_IOCTL_FIFO_READ: {
struct em1_ioctl_fifo_params p;
uint32_t w[EM1_MAX_FIFO_PAYLOAD];
int res;
if (copy_from_user(&p, (void*)arg, sizeof(p)))
return -EFAULT;
if (p.count > EM1_MAX_FIFO_PAYLOAD)
return -EINVAL;
res = em1_ioctl_fifo_read(pv, p.count, w);
if (!res && copy_to_user(p.words, w, p.count * sizeof(uint32_t)))
return -EFAULT;
return res;
}
}
return 0;
}
/*
* Local Variables:
* c-file-style: "linux"
* indent-tabs-mode: t
* tab-width: 8
* End:
*/
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "em1_drv.h"
int em1_mmap(struct file *filp, struct vm_area_struct *vma)
{
int i;
struct em1_file_s *fpv = filp->private_data;
struct em1_mmap_ctx * mctx;
size_t size = vma->vm_end - vma->vm_start;
void * virt;
dma_addr_t phys;
printk(KERN_DEBUG "exmimo1 : mmap()\n");
if (vma->vm_end <= vma->vm_start)
return -EINVAL;
for (i = 0; i < MAX_EM1_MMAP; i++) {
mctx = fpv->mmap_list + i;
if (mctx->virt == 0)
break;
}
if (i == MAX_EM1_MMAP)
return -ENOMEM;
virt = pci_alloc_consistent(fpv->pv->pdev, size, &phys);
if (virt < 0)
return -EINVAL;
if (remap_pfn_range(vma, vma->vm_start, phys >> PAGE_SHIFT, size, vma->vm_page_prot))
return -EAGAIN;
mctx->virt = virt;
mctx->phys = phys;
mctx->size = size;
return 0;
}
/*
* Local Variables:
* c-file-style: "linux"
* indent-tabs-mode: t
* tab-width: 8
* End:
*/
This diff is collapsed.
# compiles the example
OPENAIRTARGETS_DIR ?=../../../..
OPENAIROBJS += $(OPENAIRTARGETS_DIR)/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.o
CFLAGS += -I$(OPENAIRTARGETS_DIR)/ARCH/EXMIMO/USERSPACE/LIB -I$(OPENAIRTARGETS_DIR)/ARCH/EXMIMO/DEFS
example: example.o $(OPENAIROBJS)
gcc -o $@ $(CFLAGS) -lm $(OPENAIROBJS) $<
clean:
rm -f *.o *~
rm -f example
This diff is collapsed.
This diff is collapsed.
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#define TARGET_RX_POWER 50 // Target digital power for the AGC
#define TARGET_RX_POWER_MAX 53 // Maximum digital power for AGC
#define TARGET_RX_POWER_MIN 48 // Minimum digital power for AGC
#ifndef min
#define min(a,b) (((a)<(b))?(a):(b))
#define max(a,b) (((a)>(b))?(a):(b))
#endif
void gain_control_all (unsigned int rx_power_fil_dB, unsigned int card);
void gain_control (unsigned int rx_power_fil_dB, unsigned int ant, unsigned int card);
This diff is collapsed.
This diff is collapsed.
updatefw: updatefw.c
$(CC) updatefw.c -o updatefw -I../../DEFS
clean:
rm -f updatefw
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
function [sig,sig_length] = OFDM_TX(num_carriers,num_zeros,prefix_length,input)
% OFDM Transmitter - DC removed
% sig is the output signal
% length is the length of the output signal
% num_carriers - number of sub-carriers (power of 2)
% num_zeros - number of zeros minus 1 (DC) in output spectrum (odd)
% prefix_length - length of cyclic prefix
% input - input dimensions (length = number_carriers - num_zeros - 1)
if (length(input) + num_zeros + 1 ~= num_carriers)
fprintf('error in lengths\n');
return;
end
ext_input = [0 input(1:length(input)/2) zeros(1,num_zeros) input((1+length(input)/2) : length(input))];
output_1 = ifft(ext_input);
sig = [output_1((num_carriers - prefix_length + 1) : num_carriers) output_1];
sig_length = length(sig);
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
vlen=76800
chan=2
gainimb_rx = -0.0020; phaseimb_rx = -2.38; % ExMIMO1 / lime1, VGAgain2 = 0, 1.9 GHz
gainimb_rx = 0.55; phaseimb_rx = 24.3; % ExMIMO1 / lime1, VGAgain2 = 0, 1.9 GHz
phaseimb_rx = phaseimb_rx/180*pi; % phaser imb in radians
beta_rx = (1/2)*(1 + (1+ gainimb_rx) * exp(1i*phaseimb_rx));
alpha_rx = (1/2)*(1 - (1+ gainimb_rx) * exp(-1i*phaseimb_rx));
den=abs(beta_rx)^2-abs(alpha_rx)^2;
beta_rx=beta_rx/den;
alpha_rx=alpha_rx/den;
s2 = beta_rx.*s + alpha_rx.*conj(s);
hold off ; plot(20*log10(abs(fftshift(fft(s2(:,chan)))))); grid on;
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment