################################################################################
# This software program is available to you under a choice of one of two 
# licenses. You may choose to be licensed under either the GNU General Public 
# License 2.0, June 1991, available at http://www.fsf.org/copyleft/gpl.html, 
# or the Intel BSD + Patent License, the text of which follows:
# 
# Recipient has requested a license and Intel Corporation ("Intel") is willing
# to grant a license for the software entitled Linux Intel Advanced Network
# Services (iANS) (the "Licensed Program") being provided by Intel Corporation.
# The following definitions apply to this license:
# 
# "Licensed Patents" means patent claims licensable by Intel Corporation which 
# are necessarily infringed by the use of sale of the Software alone or when 
# combined with the operating system referred to below.
# 
# "Recipient" means the party to whom Intel delivers this Software.
# 
# "Licensee" means Recipient and those third parties that receive a license to 
# any operating system available under the GNU General Public License 2.0 or 
# later.
# 
# Copyright (c) 1999 - 2002 Intel Corporation.
# All rights reserved.
# 
# The license is provided to Recipient and Recipient's Licensees under the 
# following terms.
# 
# Redistribution and use in source and binary forms of the Software, with or 
# without modification, are permitted provided that the following conditions 
# are met:
# 
# Redistributions of source code of the Software may retain the above 
# copyright notice, this list of conditions and the following disclaimer.
# 
# Redistributions in binary form of the Software may reproduce the above 
# copyright notice, this list of conditions and the following disclaimer in 
# the documentation and/or materials provided with the distribution.
# 
# Neither the name of Intel Corporation nor the names of its contributors 
# shall be used to endorse or promote products derived from this Software 
# without specific prior written permission.
# 
# Intel hereby grants Recipient and Licensees a non-exclusive, worldwide, 
# royalty-free patent license under Licensed Patents to make, use, sell, offer 
# to sell, import and otherwise transfer the Software, if any, in source code 
# and object code form. This license shall include changes to the Software 
# that are error corrections or other minor changes to the Software that do 
# not add functionality or features when the Software is incorporated in any 
# version of an operating system that has been distributed under the GNU 
# General Public License 2.0 or later. This patent license shall apply to the 
# combination of the Software and any operating system licensed under the GNU 
# General Public License 2.0 or later if, at the time Intel provides the 
# Software to Recipient, such addition of the Software to the then publicly 
# available versions of such operating systems available under the GNU General 
# Public License 2.0 or later (whether in gold, beta or alpha form) causes 
# such combination to be covered by the Licensed Patents. The patent license 
# shall not apply to any other combinations which include the Software. NO 
# hardware per se is licensed hereunder.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
# IMPLIED WARRANTIES OF MECHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
# ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR IT CONTRIBUTORS BE LIABLE FOR ANY 
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
# (INCLUDING, BUT NOT LIMITED, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
# ANY LOSS OF USE; DATA, OR PROFITS; OR BUSINESS INTERUPTION) HOWEVER CAUSED 
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY OR 
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
################################################################################

###############################################################################
#
# INTEL CORPORATION
#
# This software is supplied under the terms of the license included
# above.  All use of this software must be in accordance with the terms
# of that license.
# 
# Abstract: Makefile for the open portion of the Advanced Network Services
#           (ANS) module.
# 
# Environment: Kernel Mode (linux 2.2.x, 2.4.x)
#
###############################################################################


###############################################################################
# Configuration Section

TOP_DIR = ../..
CFG_FILE = Options.make
CFG = $(shell [ -e $(TOP_DIR)/$(CFG_FILE) ] && echo 1 )
ifeq ($(CFG),1)
  include $(TOP_DIR)/$(CFG_FILE)
else
  ARCH := $(shell uname -m | sed 's/i.86/ia32/')
  ifneq ($(ARCH),ia32)
    ifneq ($(ARCH),ia64)
      $(error Not an Intel architecture)
    endif
  endif

  MAKEFLAGS+=-s   #make it silent

  SMP_STATUS = $(findstring SMP, $(shell uname -v))
  ifeq ($(SMP_STATUS), SMP)
    #MAKEFLAGS+=-j
  endif

  DEBUG = 0

  ifeq ($(DEBUG),1)
    DEFINES = #-DMEM_DEBUG #-g
  endif
endif

###############################################################################
# Environment tests

# Kernel Search Path
# All the places we look for kernel source
KSP :=  /lib/modules/$(shell uname -r)/build \
        /usr/src/linux-$(shell uname -r) \
        /usr/src/linux-$(shell uname -r | sed 's/-.*//') \
        /usr/src/kernel-headers-$(shell uname -r) \
        /usr/src/kernel-source-$(shell uname -r) \
        /usr/src/linux-$(shell uname -r | sed 's/\([0-9]*\.[0-9]*\)\..*/\1/') \
        /usr/src/linux

# prune the list down to only values that exist
# and have an include/linux subdirectory
test_dir = $(shell [ -e $(dir)/include/linux ] && echo $(dir))
KSP := $(foreach dir, $(KSP), $(test_dir))

# we will use the first valid entry in the search path
KSRC := $(firstword $(KSP))

ifeq (,$(KSRC))
  $(error Linux kernel source not found)
endif

# files we get information from in KSRC
INC_PATH  := $(KSRC)/include
KVER_FILE := $(INC_PATH)/linux/version.h
KCFG_FILE := $(INC_PATH)/linux/config.h

ifeq (,$(wildcard $(KVER_FILE)))
  $(error Linux kernel source not configured - missing version.h)
endif

ifeq (,$(wildcard $(KCFG_FILE)))
  $(error Linux kernel source not configured - missing config.h)
endif

# Pick a compiler
# All known compilers
ifneq (,$(findstring egcs-2.91.66, $(shell cat /proc/version)))
  CC := kgcc gcc cc
else
  CC := gcc cc
endif
# prune the list to only values that exist
test_cc = $(shell which $(cc) > /dev/null 2>&1 && echo $(cc))
CC := $(foreach cc, $(CC), $(test_cc))
# we will use the first valid entry in the list
CC := $(firstword $(CC))

# get the kernel version
KVER := $(shell $(CC) $(CFLAGS_EXTRA) -I$(INC_PATH) -E -dM $(KVER_FILE) | grep UTS_RELEASE | awk '{ print $$3 }' | sed 's/\"//g')

ifneq ($(KVER),$(shell uname -r))
  $(warning ***)
  $(warning *** Warning: kernel source version ($(KVER)))
  $(warning *** does not match running kernel  ($(shell uname -r)))
  $(warning *** Continuing with build,)
  $(warning *** resulting driver may not be what you want)
  $(warning ***)
endif

# look for SMP support in config.h
SMP := $(shell $(CC) $(CFLAGS_EXTRA) -I$(INC_PATH) -E -dM $(KCFG_FILE) | grep CONFIG_SMP | awk '{ print $$3; }')
ifneq ($(SMP), 1)
  SMP := 0
endif

ifneq ($(SMP),$(shell uname -a | grep SMP > /dev/null 2>&1 && echo 1 || echo 0))
  $(warning ***)
ifeq ($(SMP),1)
  $(warning *** Warning: kernel source configuration (SMP))
  $(warning *** does not match running kernel (UP))
else
  $(warning *** Warning: kernel source configuration (UP))
  $(warning *** does not match running kernel (SMP))
endif
  $(warning *** Continuing with build,)
  $(warning *** resulting driver may not be what you want)
  $(warning ***)
endif

# look for MODVERSIONS support in config.h
MODVERSIONS := $(shell $(CC) $(CFLAGS_EXTRA) -I$(INC_PATH) -E -dM $(KCFG_FILE) | grep CONFIG_MODVERSIONS | awk '{ print $$3 }')
ifneq ($(MODVERSIONS), 1)
  MODVERSIONS := 0
endif


###############################################################################
# Install paths

# pick an appropriate module install path
ifneq (,$(wildcard /lib/modules/$(KVER)/kernel))
  MOD_DIR := /lib/modules/$(KVER)/kernel/drivers/net
else
  MOD_DIR := /lib/modules/$(KVER)/net
endif

# pick an appropriate MAN install path
ifeq (,$(MAN_DIR))
  # find the best place to install the man page
  MANPATH := $(shell (manpath 2>/dev/null || echo $MANPATH) | sed 's/:/ /g')
  ifneq (,$(MANPATH))
    # test based on inclusion in MANPATH
    test_dir = $(findstring $(dir), $(MANPATH))
  else
    # no MANPATH, test based on directory existence
    test_dir = $(shell [ -e $(dir) ] && echo $(dir))
  endif
  # our preferred install path
  MAN_DIR := /usr/share/man /usr/man /usr/local/man
  MAN_DIR := $(foreach dir, $(MAN_DIR), $(test_dir))
  MAN_DIR := $(firstword $(MAN_DIR))
endif
ifeq (,$(MAN_DIR))
  # fallback to /usr/man
  MAN_DIR := /usr/man
endif

# pick an appropriate BIN install path
BIN_DIR = /usr/sbin

###############################################################################
# Driver files

OBJECTS   = ians_base.o        \
            ians_kernel.o      \
            lib/incg_dev.o     \
            lib/incg_gp_mem.o  \
            lib/incg_locks.o   \
            lib/incg_message.o \
            lib/incg_pci.o     \
            lib/incg_stats.o   \
            lib/incg_timer.o   \
            lib/incg_types.o   \
            lib/incg_utils.o

CORE_DIR  = ../bin/$(ARCH)
CORE_OBJ  = ians_core.o
CORE_BIN1 = ianscfg
CORE_BIN2 = iansd
MODULE    = ians.o
MAN_SECT  = 1
MAN_FILE  = $(CORE_BIN1).$(MAN_SECT)
TARGET    = $(CORE_DIR)/$(MODULE)
LINK_OBJS = $(OBJECTS) $(CORE_DIR)/$(CORE_OBJ)
SOURCES   = $(OBJECTS:.o=.c)

###############################################################################
# Build flags

# standard module flags
INCLUDES = -I$(INC_PATH) -I.
DEFINES  += -DLINUX -D__KERNEL__ -DMODULE -pipe
MODE_CONFIG = "module $(MODULE) built for kernel $(KVER)\n"

# Configuration dependant flags
# If SMP is supported, add the necessary flags
ifeq ($(SMP),1)
  DEFINES+=-D__SMP__ -DCONFIG_SMP
  MODE_CONFIG+="\nSMP         Enabled"
else
  MODE_CONFIG+="\nSMP         Disabled"
endif

# If MODVERSIONS is supported, add the necessary flags
ifeq ($(MODVERSIONS),1)
  DEFINES+=-DMODVERSIONS -include $(KSRC)/include/linux/modversions.h
  MODE_CONFIG+="\nMODVERSIONS Enabled"
else
  MODE_CONFIG+="\nMODVERSIONS Disabled"
endif

# Diagnostics flags
ifeq ($(DEBUG),1)
  DEFINES += -DIANS_DEBUG
  OPTIMIZE_FLAGS = -O1 -fno-omit-frame-pointer
  WARNING_FLAGS  = -Wall -Wstrict-prototypes #-Winline
else
  OPTIMIZE_FLAGS = -O3 -fomit-frame-pointer
  WARNING_FLAGS  = -Wstrict-prototypes
endif

# Sum it all up
CFLAGS = $(DEFINES) $(INCLUDES) $(OPTIMIZE_FLAGS) $(WARNING_FLAGS) $(CFLAGS_EXTRA)


###############################################################################
# Build rules

all: $(TARGET)

$(TARGET): $(OBJECTS)
	@echo "Linking $@"
	ld -r $(LINK_OBJS) -o $@
	@echo
	@echo
	@echo "**************************************************"
	@echo -e $(MODE_CONFIG)
	@echo "**************************************************"
	@echo

%.o: %.c
	@echo "  Compiling $< ..."
	$(CC) $(CFLAGS) -c $< -o $@

$(MAN_FILE).gz: ../$(MAN_FILE)
	gzip -c $< > $@

install: $(TARGET) $(MAN_FILE).gz
	install -D -m 444 $(CORE_DIR)/$(MODULE) $(INSTALL_ROOT)$(MOD_DIR)/$(MODULE)
	@echo "module $(MODULE) installed under $(INSTALL_ROOT)$(MOD_DIR)"

	install -D -m 544 $(CORE_DIR)/$(CORE_BIN1) $(INSTALL_ROOT)$(BIN_DIR)/$(CORE_BIN1)
	@echo "utility $(CORE_BIN1) installed under $(INSTALL_ROOT)$(BIN_DIR)"

	install -D -m 544 $(CORE_DIR)/$(CORE_BIN2) $(INSTALL_ROOT)$(BIN_DIR)/$(CORE_BIN2)
	@echo "daemon $(CORE_BIN2) installed under $(INSTALL_ROOT)$(BIN_DIR)"

	install -D -m 444 $(MAN_FILE).gz $(INSTALL_ROOT)$(MAN_DIR)/man$(MAN_SECT)/$(MAN_FILE).gz
	@echo "man page $(MAN_FILE).gz installed under $(INSTALL_ROOT)$(MAN_DIR)/man$(MAN_SECT)"

ifeq (,$(INSTALL_ROOT))
	depmod -a || true
	man -c -P'cat > /dev/null' $(MAN_FILE:.$(MAN_SECT)=) || true
else
	depmod -b $(INSTALL_ROOT) -a || true
endif

uninstall:
	if [ -e $(MOD_DIR)/$(MODULE) ] ; then \
	   rm -f $(MOD_DIR)/$(MODULE) ; \
	fi

	if [ -e $(BIN_DIR)/$(CORE_BIN1) ] ; then \
	   rm -f $(BIN_DIR)/$(CORE_BIN1) ; \
	fi

	if [ -e $(BIN_DIR)/$(CORE_BIN2) ] ; then \
	   rm -f $(BIN_DIR)/$(CORE_BIN2) ; \
	fi

	if [ -e $(MAN_DIR)/man$(MAN_SECT)/$(MAN_FILE).gz ] ; then \
	   rm -f $(MAN_DIR)/man$(MAN_SECT)/$(MAN_FILE).gz ; \
	fi

	depmod -a $(KVER) || true

depend:
	makedepend -f .depend -- $(CFLAGS) -- $(SOURCES)

clean:
	rm -f *.o lib/*.o *~ lib/*~ $(MAN_FILE).gz

veryclean: clean
	rm -f $(TARGET)
	echo -n > .depend

options:
	@echo "SMP=[0/1]         compile with smp disabled/enabled"
	@echo "MODVERSIONS=[0/1] compile with modeversions disabled/enabled"
	@echo " (Default values are taken from the kernel headers)"

test:
	@echo SMP=$(SMP)
	@echo MODVERSIONS=$(MODVERSIONS)
	@echo ARCH=$(ARCH)
	@echo DEBUG=$(DEBUG)
	@echo KSRC=$(KSRC)
	@echo CC=$(CC)
	@echo KVER=$(KVER)
	@echo INSTALL_ROOT=$(INSTALL_ROOT)
	@echo MOD_DIR=$(INSTALL_ROOT)$(MOD_DIR)
	@echo MAN_DIR=$(INSTALL_ROOT)$(MAN_DIR)
	@echo BIN_DIR=$(INSTALL_ROOT)$(BIN_DIR)
	@echo DEFINES=$(DEFINES)
	@echo INCLUDES=$(INCLUDES)
	@echo OPTIMIZE_FLAGS=$(OPTIMIZE_FLAGS)
	@echo WARNING_FLAGS=$(WARNING_FLAGS)
	@echo CFLAGS=$(CFLAGS)

include .depend
