mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-24 20:30:53 +07:00
Merge branch 'staging-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6
* 'staging-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6: (510 commits) staging: speakup: fix failure handling staging: usbip: remove double giveback of URB Staging: batman-adv: Remove batman-adv from staging Staging: hv: Use only one txf buffer per channel and kmalloc/GFP_KERNEL on initialize staging: hv: remove unneeded osd_schedule_callback staging: hv: convert channel_mgmt.c to not call osd_schedule_callback staging: hv: convert vmbus_on_msg_dpc to not call osd_schedule_callback staging: brcm80211: Fix WL_<type> logging macros Staging: IIO: DDS: AD9833 / AD9834 driver Staging: IIO: dds.h convenience macros Staging: IIO: Direct digital synthesis abi documentation staging: brcm80211: Convert ETHER_TYPE_802_1X to ETH_P_PAE staging: brcm80211: Remove unused ETHER_TYPE_<foo> #defines staging: brcm80211: Remove ETHER_HDR_LEN, use ETH_HLEN staging: brcm80211: Convert ETHER_ADDR_LEN to ETH_ALEN staging: brcm80211: Convert ETHER_IS<FOO> to is_<foo>_ether_addr staging: brcm80211: Remove unused ether_<foo> #defines and struct staging: brcm80211: Convert ETHER_IS_MULTI to is_multicast_ether_addr staging: brcm80211: Remove unused #defines ETHER_<foo>_LOCALADDR Staging: comedi: Fix checkpatch.pl issues in file s526.c ... Fix up trivial conflict in drivers/video/udlfb.c
This commit is contained in:
commit
949f6711b8
@ -1423,7 +1423,9 @@ F: drivers/net/tg3.*
|
|||||||
BROADCOM BRCM80211 IEEE802.11n WIRELESS DRIVER
|
BROADCOM BRCM80211 IEEE802.11n WIRELESS DRIVER
|
||||||
M: Brett Rudley <brudley@broadcom.com>
|
M: Brett Rudley <brudley@broadcom.com>
|
||||||
M: Henry Ptasinski <henryp@broadcom.com>
|
M: Henry Ptasinski <henryp@broadcom.com>
|
||||||
M: Nohee Ko <noheek@broadcom.com>
|
M: Dowan Kim <dowan@broadcom.com>
|
||||||
|
M: Roland Vossen <rvossen@broadcom.com>
|
||||||
|
M: Arend van Spriel <arend@broadcom.com>
|
||||||
L: linux-wireless@vger.kernel.org
|
L: linux-wireless@vger.kernel.org
|
||||||
S: Supported
|
S: Supported
|
||||||
F: drivers/staging/brcm80211/
|
F: drivers/staging/brcm80211/
|
||||||
|
@ -119,6 +119,8 @@ source "drivers/staging/vme/Kconfig"
|
|||||||
|
|
||||||
source "drivers/staging/memrar/Kconfig"
|
source "drivers/staging/memrar/Kconfig"
|
||||||
|
|
||||||
|
source "drivers/staging/sep/Kconfig"
|
||||||
|
|
||||||
source "drivers/staging/iio/Kconfig"
|
source "drivers/staging/iio/Kconfig"
|
||||||
|
|
||||||
source "drivers/staging/zram/Kconfig"
|
source "drivers/staging/zram/Kconfig"
|
||||||
@ -127,8 +129,6 @@ source "drivers/staging/wlags49_h2/Kconfig"
|
|||||||
|
|
||||||
source "drivers/staging/wlags49_h25/Kconfig"
|
source "drivers/staging/wlags49_h25/Kconfig"
|
||||||
|
|
||||||
source "drivers/staging/batman-adv/Kconfig"
|
|
||||||
|
|
||||||
source "drivers/staging/samsung-laptop/Kconfig"
|
source "drivers/staging/samsung-laptop/Kconfig"
|
||||||
|
|
||||||
source "drivers/staging/sm7xx/Kconfig"
|
source "drivers/staging/sm7xx/Kconfig"
|
||||||
@ -141,8 +141,6 @@ source "drivers/staging/cxt1e1/Kconfig"
|
|||||||
|
|
||||||
source "drivers/staging/ti-st/Kconfig"
|
source "drivers/staging/ti-st/Kconfig"
|
||||||
|
|
||||||
source "drivers/staging/adis16255/Kconfig"
|
|
||||||
|
|
||||||
source "drivers/staging/xgifb/Kconfig"
|
source "drivers/staging/xgifb/Kconfig"
|
||||||
|
|
||||||
source "drivers/staging/msm/Kconfig"
|
source "drivers/staging/msm/Kconfig"
|
||||||
@ -175,5 +173,9 @@ source "drivers/staging/intel_sst/Kconfig"
|
|||||||
|
|
||||||
source "drivers/staging/speakup/Kconfig"
|
source "drivers/staging/speakup/Kconfig"
|
||||||
|
|
||||||
|
source "drivers/staging/cptm1217/Kconfig"
|
||||||
|
|
||||||
|
source "drivers/staging/ste_rmi4/Kconfig"
|
||||||
|
|
||||||
endif # !STAGING_EXCLUDE_BUILD
|
endif # !STAGING_EXCLUDE_BUILD
|
||||||
endif # STAGING
|
endif # STAGING
|
||||||
|
@ -42,18 +42,17 @@ obj-$(CONFIG_VT6656) += vt6656/
|
|||||||
obj-$(CONFIG_HYPERV) += hv/
|
obj-$(CONFIG_HYPERV) += hv/
|
||||||
obj-$(CONFIG_VME_BUS) += vme/
|
obj-$(CONFIG_VME_BUS) += vme/
|
||||||
obj-$(CONFIG_MRST_RAR_HANDLER) += memrar/
|
obj-$(CONFIG_MRST_RAR_HANDLER) += memrar/
|
||||||
|
obj-$(CONFIG_DX_SEP) += sep/
|
||||||
obj-$(CONFIG_IIO) += iio/
|
obj-$(CONFIG_IIO) += iio/
|
||||||
obj-$(CONFIG_ZRAM) += zram/
|
obj-$(CONFIG_ZRAM) += zram/
|
||||||
obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/
|
obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/
|
||||||
obj-$(CONFIG_WLAGS49_H25) += wlags49_h25/
|
obj-$(CONFIG_WLAGS49_H25) += wlags49_h25/
|
||||||
obj-$(CONFIG_BATMAN_ADV) += batman-adv/
|
|
||||||
obj-$(CONFIG_SAMSUNG_LAPTOP) += samsung-laptop/
|
obj-$(CONFIG_SAMSUNG_LAPTOP) += samsung-laptop/
|
||||||
obj-$(CONFIG_FB_SM7XX) += sm7xx/
|
obj-$(CONFIG_FB_SM7XX) += sm7xx/
|
||||||
obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l/
|
obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l/
|
||||||
obj-$(CONFIG_CRYSTALHD) += crystalhd/
|
obj-$(CONFIG_CRYSTALHD) += crystalhd/
|
||||||
obj-$(CONFIG_CXT1E1) += cxt1e1/
|
obj-$(CONFIG_CXT1E1) += cxt1e1/
|
||||||
obj-$(CONFIG_TI_ST) += ti-st/
|
obj-$(CONFIG_TI_ST) += ti-st/
|
||||||
obj-$(CONFIG_ADIS16255) += adis16255/
|
|
||||||
obj-$(CONFIG_FB_XGI) += xgifb/
|
obj-$(CONFIG_FB_XGI) += xgifb/
|
||||||
obj-$(CONFIG_MSM_STAGING) += msm/
|
obj-$(CONFIG_MSM_STAGING) += msm/
|
||||||
obj-$(CONFIG_EASYCAP) += easycap/
|
obj-$(CONFIG_EASYCAP) += easycap/
|
||||||
@ -68,3 +67,5 @@ obj-$(CONFIG_BCM_WIMAX) += bcm/
|
|||||||
obj-$(CONFIG_FT1000) += ft1000/
|
obj-$(CONFIG_FT1000) += ft1000/
|
||||||
obj-$(CONFIG_SND_INTEL_SST) += intel_sst/
|
obj-$(CONFIG_SND_INTEL_SST) += intel_sst/
|
||||||
obj-$(CONFIG_SPEAKUP) += speakup/
|
obj-$(CONFIG_SPEAKUP) += speakup/
|
||||||
|
obj-$(CONFIG_TOUCHSCREEN_CLEARPAD_TM1217) += cptm1217/
|
||||||
|
obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += ste_rmi4/
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
config ADIS16255
|
|
||||||
tristate "Analog Devices ADIS16250/16255"
|
|
||||||
depends on SPI && SYSFS
|
|
||||||
---help---
|
|
||||||
If you say yes here you get support for the Analog Devices
|
|
||||||
ADIS16250/16255 Low Power Gyroscope. The driver exposes
|
|
||||||
orientation and gyroscope value, as well as sample rate
|
|
||||||
to the sysfs.
|
|
||||||
|
|
||||||
This driver can also be built as a module. If so, the module
|
|
||||||
will be called adis16255.
|
|
@ -1 +0,0 @@
|
|||||||
obj-$(CONFIG_ADIS16255) += adis16255.o
|
|
@ -1,468 +0,0 @@
|
|||||||
/*
|
|
||||||
* Analog Devices ADIS16250/ADIS16255 Low Power Gyroscope
|
|
||||||
*
|
|
||||||
* Written by: Matthias Brugger <m_brugger@web.de>
|
|
||||||
*
|
|
||||||
* Copyright (C) 2010 Fraunhofer Institute for Integrated Circuits
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the
|
|
||||||
* Free Software Foundation, Inc.,
|
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The driver just has a bare interface to the sysfs (sample rate in Hz,
|
|
||||||
* orientation (x, y, z) and gyroscope data in °/sec.
|
|
||||||
*
|
|
||||||
* It should be added to iio subsystem when this has left staging.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/device.h>
|
|
||||||
#include <linux/list.h>
|
|
||||||
#include <linux/errno.h>
|
|
||||||
#include <linux/mutex.h>
|
|
||||||
#include <linux/slab.h>
|
|
||||||
|
|
||||||
#include <linux/interrupt.h>
|
|
||||||
#include <linux/sysfs.h>
|
|
||||||
#include <linux/stat.h>
|
|
||||||
#include <linux/delay.h>
|
|
||||||
|
|
||||||
#include <linux/gpio.h>
|
|
||||||
|
|
||||||
#include <linux/spi/spi.h>
|
|
||||||
#include <linux/workqueue.h>
|
|
||||||
|
|
||||||
#include "adis16255.h"
|
|
||||||
|
|
||||||
#define ADIS_STATUS 0x3d
|
|
||||||
#define ADIS_SMPL_PRD_MSB 0x37
|
|
||||||
#define ADIS_SMPL_PRD_LSB 0x36
|
|
||||||
#define ADIS_MSC_CTRL_MSB 0x35
|
|
||||||
#define ADIS_MSC_CTRL_LSB 0x34
|
|
||||||
#define ADIS_GPIO_CTRL 0x33
|
|
||||||
#define ADIS_ALM_SMPL1 0x25
|
|
||||||
#define ADIS_ALM_MAG1 0x21
|
|
||||||
#define ADIS_GYRO_SCALE 0x17
|
|
||||||
#define ADIS_GYRO_OUT 0x05
|
|
||||||
#define ADIS_SUPPLY_OUT 0x03
|
|
||||||
#define ADIS_ENDURANCE 0x01
|
|
||||||
|
|
||||||
/*
|
|
||||||
* data structure for every sensor
|
|
||||||
*
|
|
||||||
* @dev: Driver model representation of the device.
|
|
||||||
* @spi: Pointer to the spi device which will manage i/o to spi bus.
|
|
||||||
* @data: Last read data from device.
|
|
||||||
* @irq_adis: GPIO Number of IRQ signal
|
|
||||||
* @irq: irq line manage by kernel
|
|
||||||
* @negative: indicates if sensor is upside down (negative == 1)
|
|
||||||
* @direction: indicates axis (x, y, z) the sensor is meassuring
|
|
||||||
*/
|
|
||||||
struct spi_adis16255_data {
|
|
||||||
struct device dev;
|
|
||||||
struct spi_device *spi;
|
|
||||||
s16 data;
|
|
||||||
int irq;
|
|
||||||
u8 negative;
|
|
||||||
char direction;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
static int spi_adis16255_read_data(struct spi_adis16255_data *spiadis,
|
|
||||||
u8 adr,
|
|
||||||
u8 *rbuf)
|
|
||||||
{
|
|
||||||
struct spi_device *spi = spiadis->spi;
|
|
||||||
struct spi_message msg;
|
|
||||||
struct spi_transfer xfer1, xfer2;
|
|
||||||
u8 *buf, *rx;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
buf = kzalloc(4, GFP_KERNEL);
|
|
||||||
if (buf == NULL)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
rx = kzalloc(4, GFP_KERNEL);
|
|
||||||
if (rx == NULL) {
|
|
||||||
ret = -ENOMEM;
|
|
||||||
goto err_buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
buf[0] = adr;
|
|
||||||
|
|
||||||
spi_message_init(&msg);
|
|
||||||
memset(&xfer1, 0, sizeof(xfer1));
|
|
||||||
memset(&xfer2, 0, sizeof(xfer2));
|
|
||||||
|
|
||||||
xfer1.tx_buf = buf;
|
|
||||||
xfer1.rx_buf = buf + 2;
|
|
||||||
xfer1.len = 2;
|
|
||||||
xfer1.delay_usecs = 9;
|
|
||||||
|
|
||||||
xfer2.tx_buf = rx + 2;
|
|
||||||
xfer2.rx_buf = rx;
|
|
||||||
xfer2.len = 2;
|
|
||||||
|
|
||||||
spi_message_add_tail(&xfer1, &msg);
|
|
||||||
spi_message_add_tail(&xfer2, &msg);
|
|
||||||
|
|
||||||
ret = spi_sync(spi, &msg);
|
|
||||||
if (ret == 0) {
|
|
||||||
rbuf[0] = rx[0];
|
|
||||||
rbuf[1] = rx[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
kfree(rx);
|
|
||||||
err_buf:
|
|
||||||
kfree(buf);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int spi_adis16255_write_data(struct spi_adis16255_data *spiadis,
|
|
||||||
u8 adr1,
|
|
||||||
u8 adr2,
|
|
||||||
u8 *wbuf)
|
|
||||||
{
|
|
||||||
struct spi_device *spi = spiadis->spi;
|
|
||||||
struct spi_message msg;
|
|
||||||
struct spi_transfer xfer1, xfer2;
|
|
||||||
u8 *buf, *rx;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
buf = kmalloc(4, GFP_KERNEL);
|
|
||||||
if (buf == NULL)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
rx = kzalloc(4, GFP_KERNEL);
|
|
||||||
if (rx == NULL) {
|
|
||||||
ret = -ENOMEM;
|
|
||||||
goto err_buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
spi_message_init(&msg);
|
|
||||||
memset(&xfer1, 0, sizeof(xfer1));
|
|
||||||
memset(&xfer2, 0, sizeof(xfer2));
|
|
||||||
|
|
||||||
buf[0] = adr1 | 0x80;
|
|
||||||
buf[1] = *wbuf;
|
|
||||||
|
|
||||||
buf[2] = adr2 | 0x80;
|
|
||||||
buf[3] = *(wbuf + 1);
|
|
||||||
|
|
||||||
xfer1.tx_buf = buf;
|
|
||||||
xfer1.rx_buf = rx;
|
|
||||||
xfer1.len = 2;
|
|
||||||
xfer1.delay_usecs = 9;
|
|
||||||
|
|
||||||
xfer2.tx_buf = buf+2;
|
|
||||||
xfer2.rx_buf = rx+2;
|
|
||||||
xfer2.len = 2;
|
|
||||||
|
|
||||||
spi_message_add_tail(&xfer1, &msg);
|
|
||||||
spi_message_add_tail(&xfer2, &msg);
|
|
||||||
|
|
||||||
ret = spi_sync(spi, &msg);
|
|
||||||
if (ret != 0)
|
|
||||||
dev_warn(&spi->dev, "write data to %#x %#x failed\n",
|
|
||||||
buf[0], buf[2]);
|
|
||||||
|
|
||||||
kfree(rx);
|
|
||||||
err_buf:
|
|
||||||
kfree(buf);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
static irqreturn_t adis_irq_thread(int irq, void *dev_id)
|
|
||||||
{
|
|
||||||
struct spi_adis16255_data *spiadis = dev_id;
|
|
||||||
int status;
|
|
||||||
u16 value = 0;
|
|
||||||
|
|
||||||
status = spi_adis16255_read_data(spiadis, ADIS_GYRO_OUT, (u8 *)&value);
|
|
||||||
if (status != 0) {
|
|
||||||
dev_warn(&spiadis->spi->dev, "SPI FAILED\n");
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* perform on new data only... */
|
|
||||||
if (value & 0x8000) {
|
|
||||||
/* delete error and new data bit */
|
|
||||||
value = value & 0x3fff;
|
|
||||||
/* set negative value */
|
|
||||||
if (value & 0x2000)
|
|
||||||
value = value | 0xe000;
|
|
||||||
|
|
||||||
if (likely(spiadis->negative))
|
|
||||||
value = -value;
|
|
||||||
|
|
||||||
spiadis->data = (s16) value;
|
|
||||||
}
|
|
||||||
|
|
||||||
exit:
|
|
||||||
return IRQ_HANDLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
ssize_t adis16255_show_data(struct device *device,
|
|
||||||
struct device_attribute *da,
|
|
||||||
char *buf)
|
|
||||||
{
|
|
||||||
struct spi_adis16255_data *spiadis = dev_get_drvdata(device);
|
|
||||||
return snprintf(buf, PAGE_SIZE, "%d\n", spiadis->data);
|
|
||||||
}
|
|
||||||
DEVICE_ATTR(data, S_IRUGO , adis16255_show_data, NULL);
|
|
||||||
|
|
||||||
ssize_t adis16255_show_direction(struct device *device,
|
|
||||||
struct device_attribute *da,
|
|
||||||
char *buf)
|
|
||||||
{
|
|
||||||
struct spi_adis16255_data *spiadis = dev_get_drvdata(device);
|
|
||||||
return snprintf(buf, PAGE_SIZE, "%c\n", spiadis->direction);
|
|
||||||
}
|
|
||||||
DEVICE_ATTR(direction, S_IRUGO , adis16255_show_direction, NULL);
|
|
||||||
|
|
||||||
ssize_t adis16255_show_sample_rate(struct device *device,
|
|
||||||
struct device_attribute *da,
|
|
||||||
char *buf)
|
|
||||||
{
|
|
||||||
struct spi_adis16255_data *spiadis = dev_get_drvdata(device);
|
|
||||||
int status = 0;
|
|
||||||
u16 value = 0;
|
|
||||||
int ts = 0;
|
|
||||||
|
|
||||||
status = spi_adis16255_read_data(spiadis, ADIS_SMPL_PRD_MSB,
|
|
||||||
(u8 *)&value);
|
|
||||||
if (status != 0)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (value & 0x80) {
|
|
||||||
/* timebase = 60.54 ms */
|
|
||||||
ts = 60540 * ((0x7f & value) + 1);
|
|
||||||
} else {
|
|
||||||
/* timebase = 1.953 ms */
|
|
||||||
ts = 1953 * ((0x7f & value) + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return snprintf(buf, PAGE_SIZE, "%d\n", (1000*1000)/ts);
|
|
||||||
}
|
|
||||||
DEVICE_ATTR(sample_rate, S_IRUGO , adis16255_show_sample_rate, NULL);
|
|
||||||
|
|
||||||
static struct attribute *adis16255_attributes[] = {
|
|
||||||
&dev_attr_data.attr,
|
|
||||||
&dev_attr_direction.attr,
|
|
||||||
&dev_attr_sample_rate.attr,
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct attribute_group adis16255_attr_group = {
|
|
||||||
.attrs = adis16255_attributes,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
static int spi_adis16255_shutdown(struct spi_adis16255_data *spiadis)
|
|
||||||
{
|
|
||||||
u16 value = 0;
|
|
||||||
/* turn sensor off */
|
|
||||||
spi_adis16255_write_data(spiadis,
|
|
||||||
ADIS_SMPL_PRD_MSB, ADIS_SMPL_PRD_LSB,
|
|
||||||
(u8 *)&value);
|
|
||||||
spi_adis16255_write_data(spiadis,
|
|
||||||
ADIS_MSC_CTRL_MSB, ADIS_MSC_CTRL_LSB,
|
|
||||||
(u8 *)&value);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int spi_adis16255_bringup(struct spi_adis16255_data *spiadis)
|
|
||||||
{
|
|
||||||
int status = 0;
|
|
||||||
u16 value = 0;
|
|
||||||
|
|
||||||
status = spi_adis16255_read_data(spiadis, ADIS_GYRO_SCALE,
|
|
||||||
(u8 *)&value);
|
|
||||||
if (status != 0)
|
|
||||||
goto err;
|
|
||||||
if (value != 0x0800) {
|
|
||||||
dev_warn(&spiadis->spi->dev, "Scale factor is none default "
|
|
||||||
"value (%.4x)\n", value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* timebase = 1.953 ms, Ns = 0 -> 512 Hz sample rate */
|
|
||||||
value = 0x0001;
|
|
||||||
status = spi_adis16255_write_data(spiadis,
|
|
||||||
ADIS_SMPL_PRD_MSB, ADIS_SMPL_PRD_LSB,
|
|
||||||
(u8 *)&value);
|
|
||||||
if (status != 0)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
/* start internal self-test */
|
|
||||||
value = 0x0400;
|
|
||||||
status = spi_adis16255_write_data(spiadis,
|
|
||||||
ADIS_MSC_CTRL_MSB, ADIS_MSC_CTRL_LSB,
|
|
||||||
(u8 *)&value);
|
|
||||||
if (status != 0)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
/* wait 35 ms to finish self-test */
|
|
||||||
msleep(35);
|
|
||||||
|
|
||||||
value = 0x0000;
|
|
||||||
status = spi_adis16255_read_data(spiadis, ADIS_STATUS,
|
|
||||||
(u8 *)&value);
|
|
||||||
if (status != 0)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
if (value & 0x23) {
|
|
||||||
if (value & 0x20) {
|
|
||||||
dev_warn(&spiadis->spi->dev, "self-test error\n");
|
|
||||||
status = -ENODEV;
|
|
||||||
goto err;
|
|
||||||
} else if (value & 0x3) {
|
|
||||||
dev_warn(&spiadis->spi->dev, "Sensor voltage "
|
|
||||||
"out of range.\n");
|
|
||||||
status = -ENODEV;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set interrupt to active high on DIO0 when data ready */
|
|
||||||
value = 0x0006;
|
|
||||||
status = spi_adis16255_write_data(spiadis,
|
|
||||||
ADIS_MSC_CTRL_MSB, ADIS_MSC_CTRL_LSB,
|
|
||||||
(u8 *)&value);
|
|
||||||
if (status != 0)
|
|
||||||
goto err;
|
|
||||||
return status;
|
|
||||||
|
|
||||||
err:
|
|
||||||
spi_adis16255_shutdown(spiadis);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
static int __devinit spi_adis16255_probe(struct spi_device *spi)
|
|
||||||
{
|
|
||||||
|
|
||||||
struct adis16255_init_data *init_data = spi->dev.platform_data;
|
|
||||||
struct spi_adis16255_data *spiadis;
|
|
||||||
int status = 0;
|
|
||||||
|
|
||||||
spiadis = kzalloc(sizeof(*spiadis), GFP_KERNEL);
|
|
||||||
if (!spiadis)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
spiadis->spi = spi;
|
|
||||||
spiadis->direction = init_data->direction;
|
|
||||||
|
|
||||||
if (init_data->negative)
|
|
||||||
spiadis->negative = 1;
|
|
||||||
|
|
||||||
status = gpio_request(init_data->irq, "adis16255");
|
|
||||||
if (status != 0)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
status = gpio_direction_input(init_data->irq);
|
|
||||||
if (status != 0)
|
|
||||||
goto gpio_err;
|
|
||||||
|
|
||||||
spiadis->irq = gpio_to_irq(init_data->irq);
|
|
||||||
|
|
||||||
status = request_threaded_irq(spiadis->irq,
|
|
||||||
NULL, adis_irq_thread,
|
|
||||||
IRQF_DISABLED, "adis-driver", spiadis);
|
|
||||||
|
|
||||||
if (status != 0) {
|
|
||||||
dev_err(&spi->dev, "IRQ request failed\n");
|
|
||||||
goto gpio_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
dev_dbg(&spi->dev, "GPIO %d IRQ %d\n", init_data->irq, spiadis->irq);
|
|
||||||
|
|
||||||
dev_set_drvdata(&spi->dev, spiadis);
|
|
||||||
status = sysfs_create_group(&spi->dev.kobj, &adis16255_attr_group);
|
|
||||||
if (status != 0)
|
|
||||||
goto irq_err;
|
|
||||||
|
|
||||||
status = spi_adis16255_bringup(spiadis);
|
|
||||||
if (status != 0)
|
|
||||||
goto sysfs_err;
|
|
||||||
|
|
||||||
dev_info(&spi->dev, "spi_adis16255 driver added!\n");
|
|
||||||
|
|
||||||
return status;
|
|
||||||
|
|
||||||
sysfs_err:
|
|
||||||
sysfs_remove_group(&spiadis->spi->dev.kobj, &adis16255_attr_group);
|
|
||||||
irq_err:
|
|
||||||
free_irq(spiadis->irq, spiadis);
|
|
||||||
gpio_err:
|
|
||||||
gpio_free(init_data->irq);
|
|
||||||
err:
|
|
||||||
kfree(spiadis);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __devexit spi_adis16255_remove(struct spi_device *spi)
|
|
||||||
{
|
|
||||||
struct spi_adis16255_data *spiadis = dev_get_drvdata(&spi->dev);
|
|
||||||
|
|
||||||
spi_adis16255_shutdown(spiadis);
|
|
||||||
|
|
||||||
free_irq(spiadis->irq, spiadis);
|
|
||||||
gpio_free(irq_to_gpio(spiadis->irq));
|
|
||||||
|
|
||||||
sysfs_remove_group(&spiadis->spi->dev.kobj, &adis16255_attr_group);
|
|
||||||
|
|
||||||
kfree(spiadis);
|
|
||||||
|
|
||||||
dev_info(&spi->dev, "spi_adis16255 driver removed!\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct spi_driver spi_adis16255_drv = {
|
|
||||||
.driver = {
|
|
||||||
.name = "spi_adis16255",
|
|
||||||
.owner = THIS_MODULE,
|
|
||||||
},
|
|
||||||
.probe = spi_adis16255_probe,
|
|
||||||
.remove = __devexit_p(spi_adis16255_remove),
|
|
||||||
};
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
static int __init spi_adis16255_init(void)
|
|
||||||
{
|
|
||||||
return spi_register_driver(&spi_adis16255_drv);
|
|
||||||
}
|
|
||||||
module_init(spi_adis16255_init);
|
|
||||||
|
|
||||||
static void __exit spi_adis16255_exit(void)
|
|
||||||
{
|
|
||||||
spi_unregister_driver(&spi_adis16255_drv);
|
|
||||||
}
|
|
||||||
module_exit(spi_adis16255_exit);
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Matthias Brugger");
|
|
||||||
MODULE_DESCRIPTION("SPI device driver for ADIS16255 sensor");
|
|
||||||
MODULE_LICENSE("GPL");
|
|
@ -1,12 +0,0 @@
|
|||||||
#ifndef ADIS16255_H
|
|
||||||
#define ADIS16255_H
|
|
||||||
|
|
||||||
#include <linux/types.h>
|
|
||||||
|
|
||||||
struct adis16255_init_data {
|
|
||||||
char direction;
|
|
||||||
u8 negative;
|
|
||||||
int irq;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -70,7 +70,7 @@ module_param(start_off, uint, 0644);
|
|||||||
MODULE_PARM_DESC(start_off,
|
MODULE_PARM_DESC(start_off,
|
||||||
"Set to 1 to switch off OLED display after it is attached");
|
"Set to 1 to switch off OLED display after it is attached");
|
||||||
|
|
||||||
enum oled_pack_mode{
|
enum oled_pack_mode {
|
||||||
PACK_MODE_G1,
|
PACK_MODE_G1,
|
||||||
PACK_MODE_G50,
|
PACK_MODE_G50,
|
||||||
PACK_MODE_LAST
|
PACK_MODE_LAST
|
||||||
|
@ -876,7 +876,7 @@ HIFAckInterrupt(HIF_DEVICE *device)
|
|||||||
void
|
void
|
||||||
HIFUnMaskInterrupt(HIF_DEVICE *device)
|
HIFUnMaskInterrupt(HIF_DEVICE *device)
|
||||||
{
|
{
|
||||||
int ret;;
|
int ret;
|
||||||
|
|
||||||
AR_DEBUG_ASSERT(device != NULL);
|
AR_DEBUG_ASSERT(device != NULL);
|
||||||
AR_DEBUG_ASSERT(device->func != NULL);
|
AR_DEBUG_ASSERT(device->func != NULL);
|
||||||
@ -1188,7 +1188,7 @@ addHifDevice(struct sdio_func *func)
|
|||||||
HIF_DEVICE *hifdevice;
|
HIF_DEVICE *hifdevice;
|
||||||
AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: addHifDevice\n"));
|
AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: addHifDevice\n"));
|
||||||
AR_DEBUG_ASSERT(func != NULL);
|
AR_DEBUG_ASSERT(func != NULL);
|
||||||
hifdevice = (HIF_DEVICE *)kzalloc(sizeof(HIF_DEVICE), GFP_KERNEL);
|
hifdevice = kzalloc(sizeof(HIF_DEVICE), GFP_KERNEL);
|
||||||
AR_DEBUG_ASSERT(hifdevice != NULL);
|
AR_DEBUG_ASSERT(hifdevice != NULL);
|
||||||
#if HIF_USE_DMA_BOUNCE_BUFFER
|
#if HIF_USE_DMA_BOUNCE_BUFFER
|
||||||
hifdevice->dma_buffer = kmalloc(HIF_DMA_BUFFER_SIZE, GFP_KERNEL);
|
hifdevice->dma_buffer = kmalloc(HIF_DMA_BUFFER_SIZE, GFP_KERNEL);
|
||||||
|
@ -4439,7 +4439,7 @@ ar6000_connect_event(AR_SOFTC_T *ar, A_UINT16 channel, A_UINT8 *bssid,
|
|||||||
for (i = assoc_req_ie_pos; i < assoc_req_ie_pos + assocReqLen - 4; i++) {
|
for (i = assoc_req_ie_pos; i < assoc_req_ie_pos + assocReqLen - 4; i++) {
|
||||||
AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("%2.2x ", assocInfo[i]));
|
AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("%2.2x ", assocInfo[i]));
|
||||||
sprintf(pos, "%2.2x", assocInfo[i]);
|
sprintf(pos, "%2.2x", assocInfo[i]);
|
||||||
pos += 2;;
|
pos += 2;
|
||||||
}
|
}
|
||||||
AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n"));
|
AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n"));
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ void autofs_update_usage(struct autofs_dirhash *dh,
|
|||||||
struct autofs_dir_ent *ent)
|
struct autofs_dir_ent *ent)
|
||||||
{
|
{
|
||||||
autofs_delete_usage(ent); /* Unlink from current position */
|
autofs_delete_usage(ent); /* Unlink from current position */
|
||||||
autofs_init_usage(dh,ent); /* Relink at queue tail */
|
autofs_init_usage(dh, ent); /* Relink at queue tail */
|
||||||
}
|
}
|
||||||
|
|
||||||
struct autofs_dir_ent *autofs_expire(struct super_block *sb,
|
struct autofs_dir_ent *autofs_expire(struct super_block *sb,
|
||||||
@ -45,17 +45,18 @@ struct autofs_dir_ent *autofs_expire(struct super_block *sb,
|
|||||||
struct path path;
|
struct path path;
|
||||||
int umount_ok;
|
int umount_ok;
|
||||||
|
|
||||||
if ( list_empty(&dh->expiry_head) || sbi->catatonic )
|
if (list_empty(&dh->expiry_head) || sbi->catatonic)
|
||||||
return NULL; /* No entries */
|
return NULL; /* No entries */
|
||||||
/* We keep the list sorted by last_usage and want old stuff */
|
/* We keep the list sorted by last_usage and want old stuff */
|
||||||
ent = list_entry(dh->expiry_head.next, struct autofs_dir_ent, exp);
|
ent = list_entry(dh->expiry_head.next,
|
||||||
|
struct autofs_dir_ent, exp);
|
||||||
if (jiffies - ent->last_usage < timeout)
|
if (jiffies - ent->last_usage < timeout)
|
||||||
break;
|
break;
|
||||||
/* Move to end of list in case expiry isn't desirable */
|
/* Move to end of list in case expiry isn't desirable */
|
||||||
autofs_update_usage(dh, ent);
|
autofs_update_usage(dh, ent);
|
||||||
|
|
||||||
/* Check to see that entry is expirable */
|
/* Check to see that entry is expirable */
|
||||||
if ( ent->ino < AUTOFS_FIRST_DIR_INO )
|
if (ent->ino < AUTOFS_FIRST_DIR_INO)
|
||||||
return ent; /* Symlinks are always expirable */
|
return ent; /* Symlinks are always expirable */
|
||||||
|
|
||||||
/* Get the dentry for the autofs subdirectory */
|
/* Get the dentry for the autofs subdirectory */
|
||||||
@ -63,14 +64,15 @@ struct autofs_dir_ent *autofs_expire(struct super_block *sb,
|
|||||||
|
|
||||||
if (!path.dentry) {
|
if (!path.dentry) {
|
||||||
/* Should only happen in catatonic mode */
|
/* Should only happen in catatonic mode */
|
||||||
printk("autofs: dentry == NULL but inode range is directory, entry %s\n", ent->name);
|
printk(KERN_DEBUG "autofs: dentry == NULL but inode \
|
||||||
|
range is directory, entry %s\n", ent->name);
|
||||||
autofs_delete_usage(ent);
|
autofs_delete_usage(ent);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!path.dentry->d_inode) {
|
if (!path.dentry->d_inode) {
|
||||||
dput(path.dentry);
|
dput(path.dentry);
|
||||||
printk("autofs: negative dentry on expiry queue: %s\n",
|
printk(KERN_DEBUG "autofs: negative dentry on expiry queue: %s\n",
|
||||||
ent->name);
|
ent->name);
|
||||||
autofs_delete_usage(ent);
|
autofs_delete_usage(ent);
|
||||||
continue;
|
continue;
|
||||||
@ -80,14 +82,16 @@ struct autofs_dir_ent *autofs_expire(struct super_block *sb,
|
|||||||
point to the mounted-on-top root. */
|
point to the mounted-on-top root. */
|
||||||
if (!S_ISDIR(path.dentry->d_inode->i_mode) ||
|
if (!S_ISDIR(path.dentry->d_inode->i_mode) ||
|
||||||
!d_mountpoint(path.dentry)) {
|
!d_mountpoint(path.dentry)) {
|
||||||
DPRINTK(("autofs: not expirable (not a mounted directory): %s\n", ent->name));
|
DPRINTK(("autofs: not expirable \
|
||||||
|
(not a mounted directory): %s\n", ent->name));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
path.mnt = mnt;
|
path.mnt = mnt;
|
||||||
path_get(&path);
|
path_get(&path);
|
||||||
if (!follow_down(&path)) {
|
if (!follow_down(&path)) {
|
||||||
path_put(&path);
|
path_put(&path);
|
||||||
DPRINTK(("autofs: not expirable (not a mounted directory): %s\n", ent->name));
|
DPRINTK(("autofs: not expirable\
|
||||||
|
(not a mounted directory): %s\n", ent->name));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
while (d_mountpoint(path.dentry) && follow_down(&path))
|
while (d_mountpoint(path.dentry) && follow_down(&path))
|
||||||
@ -96,30 +100,37 @@ struct autofs_dir_ent *autofs_expire(struct super_block *sb,
|
|||||||
path_put(&path);
|
path_put(&path);
|
||||||
|
|
||||||
if (umount_ok) {
|
if (umount_ok) {
|
||||||
DPRINTK(("autofs: signaling expire on %s\n", ent->name));
|
DPRINTK(("autofs: signaling expire on %s\n",
|
||||||
|
ent->name));
|
||||||
return ent; /* Expirable! */
|
return ent; /* Expirable! */
|
||||||
}
|
}
|
||||||
DPRINTK(("autofs: didn't expire due to may_umount: %s\n", ent->name));
|
|
||||||
|
DPRINTK(("autofs: didn't expire due to may_umount: %s\n",
|
||||||
|
ent->name));
|
||||||
}
|
}
|
||||||
return NULL; /* No expirable entries */
|
return NULL; /* No expirable entries */
|
||||||
}
|
}
|
||||||
|
|
||||||
void autofs_initialize_hash(struct autofs_dirhash *dh) {
|
void autofs_initialize_hash(struct autofs_dirhash *dh)
|
||||||
|
{
|
||||||
memset(&dh->h, 0, AUTOFS_HASH_SIZE*sizeof(struct autofs_dir_ent *));
|
memset(&dh->h, 0, AUTOFS_HASH_SIZE*sizeof(struct autofs_dir_ent *));
|
||||||
INIT_LIST_HEAD(&dh->expiry_head);
|
INIT_LIST_HEAD(&dh->expiry_head);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct autofs_dir_ent *autofs_hash_lookup(const struct autofs_dirhash *dh, struct qstr *name)
|
struct autofs_dir_ent *autofs_hash_lookup(const struct autofs_dirhash *dh,
|
||||||
|
struct qstr *name)
|
||||||
{
|
{
|
||||||
struct autofs_dir_ent *dhn;
|
struct autofs_dir_ent *dhn;
|
||||||
|
|
||||||
DPRINTK(("autofs_hash_lookup: hash = 0x%08x, name = ", name->hash));
|
DPRINTK(("autofs_hash_lookup: hash = 0x%08x, name = ", name->hash));
|
||||||
autofs_say(name->name,name->len);
|
autofs_say(name->name, name->len);
|
||||||
|
|
||||||
for ( dhn = dh->h[(unsigned) name->hash % AUTOFS_HASH_SIZE] ; dhn ; dhn = dhn->next ) {
|
for (dhn = dh->h[(unsigned) name->hash % AUTOFS_HASH_SIZE];
|
||||||
if ( name->hash == dhn->hash &&
|
dhn;
|
||||||
|
dhn = dhn->next) {
|
||||||
|
if (name->hash == dhn->hash &&
|
||||||
name->len == dhn->len &&
|
name->len == dhn->len &&
|
||||||
!memcmp(name->name, dhn->name, name->len) )
|
!memcmp(name->name, dhn->name, name->len))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,9 +142,9 @@ void autofs_hash_insert(struct autofs_dirhash *dh, struct autofs_dir_ent *ent)
|
|||||||
struct autofs_dir_ent **dhnp;
|
struct autofs_dir_ent **dhnp;
|
||||||
|
|
||||||
DPRINTK(("autofs_hash_insert: hash = 0x%08x, name = ", ent->hash));
|
DPRINTK(("autofs_hash_insert: hash = 0x%08x, name = ", ent->hash));
|
||||||
autofs_say(ent->name,ent->len);
|
autofs_say(ent->name, ent->len);
|
||||||
|
|
||||||
autofs_init_usage(dh,ent);
|
autofs_init_usage(dh, ent);
|
||||||
if (ent->dentry)
|
if (ent->dentry)
|
||||||
dget(ent->dentry);
|
dget(ent->dentry);
|
||||||
|
|
||||||
@ -141,19 +152,19 @@ void autofs_hash_insert(struct autofs_dirhash *dh, struct autofs_dir_ent *ent)
|
|||||||
ent->next = *dhnp;
|
ent->next = *dhnp;
|
||||||
ent->back = dhnp;
|
ent->back = dhnp;
|
||||||
*dhnp = ent;
|
*dhnp = ent;
|
||||||
if ( ent->next )
|
if (ent->next)
|
||||||
ent->next->back = &(ent->next);
|
ent->next->back = &(ent->next);
|
||||||
}
|
}
|
||||||
|
|
||||||
void autofs_hash_delete(struct autofs_dir_ent *ent)
|
void autofs_hash_delete(struct autofs_dir_ent *ent)
|
||||||
{
|
{
|
||||||
*(ent->back) = ent->next;
|
*(ent->back) = ent->next;
|
||||||
if ( ent->next )
|
if (ent->next)
|
||||||
ent->next->back = ent->back;
|
ent->next->back = ent->back;
|
||||||
|
|
||||||
autofs_delete_usage(ent);
|
autofs_delete_usage(ent);
|
||||||
|
|
||||||
if ( ent->dentry )
|
if (ent->dentry)
|
||||||
dput(ent->dentry);
|
dput(ent->dentry);
|
||||||
kfree(ent->name);
|
kfree(ent->name);
|
||||||
kfree(ent);
|
kfree(ent);
|
||||||
@ -176,37 +187,37 @@ struct autofs_dir_ent *autofs_hash_enum(const struct autofs_dirhash *dh,
|
|||||||
bucket = (*ptr >> 16) - 1;
|
bucket = (*ptr >> 16) - 1;
|
||||||
ecount = *ptr & 0xffff;
|
ecount = *ptr & 0xffff;
|
||||||
|
|
||||||
if ( bucket < 0 ) {
|
if (bucket < 0)
|
||||||
bucket = ecount = 0;
|
bucket = ecount = 0;
|
||||||
}
|
|
||||||
|
|
||||||
DPRINTK(("autofs_hash_enum: bucket %d, entry %d\n", bucket, ecount));
|
DPRINTK(("autofs_hash_enum: bucket %d, entry %d\n", bucket, ecount));
|
||||||
|
|
||||||
ent = last ? last->next : NULL;
|
ent = last ? last->next : NULL;
|
||||||
|
|
||||||
if ( ent ) {
|
if (ent) {
|
||||||
ecount++;
|
ecount++;
|
||||||
} else {
|
} else {
|
||||||
while ( bucket < AUTOFS_HASH_SIZE ) {
|
while (bucket < AUTOFS_HASH_SIZE) {
|
||||||
ent = dh->h[bucket];
|
ent = dh->h[bucket];
|
||||||
for ( i = ecount ; ent && i ; i-- )
|
for (i = ecount ; ent && i ; i--)
|
||||||
ent = ent->next;
|
ent = ent->next;
|
||||||
|
|
||||||
if (ent) {
|
if (ent) {
|
||||||
ecount++; /* Point to *next* entry */
|
ecount++; /* Point to *next* entry */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
bucket++; ecount = 0;
|
bucket++; ecount = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if ( !ent )
|
if (!ent)
|
||||||
printk("autofs_hash_enum: nothing found\n");
|
printk(KERN_DEBUG "autofs_hash_enum: nothing found\n");
|
||||||
else {
|
else {
|
||||||
printk("autofs_hash_enum: found hash %08x, name", ent->hash);
|
printk(KERN_DEBUG "autofs_hash_enum: found hash %08x, name",
|
||||||
autofs_say(ent->name,ent->len);
|
ent->hash);
|
||||||
|
autofs_say(ent->name, ent->len);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -221,9 +232,9 @@ void autofs_hash_dputall(struct autofs_dirhash *dh)
|
|||||||
int i;
|
int i;
|
||||||
struct autofs_dir_ent *ent;
|
struct autofs_dir_ent *ent;
|
||||||
|
|
||||||
for ( i = 0 ; i < AUTOFS_HASH_SIZE ; i++ ) {
|
for (i = 0 ; i < AUTOFS_HASH_SIZE ; i++) {
|
||||||
for ( ent = dh->h[i] ; ent ; ent = ent->next ) {
|
for (ent = dh->h[i] ; ent ; ent = ent->next) {
|
||||||
if ( ent->dentry ) {
|
if (ent->dentry) {
|
||||||
dput(ent->dentry);
|
dput(ent->dentry);
|
||||||
ent->dentry = NULL;
|
ent->dentry = NULL;
|
||||||
}
|
}
|
||||||
@ -238,10 +249,10 @@ void autofs_hash_nuke(struct autofs_sb_info *sbi)
|
|||||||
int i;
|
int i;
|
||||||
struct autofs_dir_ent *ent, *nent;
|
struct autofs_dir_ent *ent, *nent;
|
||||||
|
|
||||||
for ( i = 0 ; i < AUTOFS_HASH_SIZE ; i++ ) {
|
for (i = 0 ; i < AUTOFS_HASH_SIZE ; i++) {
|
||||||
for ( ent = sbi->dirhash.h[i] ; ent ; ent = nent ) {
|
for (ent = sbi->dirhash.h[i] ; ent ; ent = nent) {
|
||||||
nent = ent->next;
|
nent = ent->next;
|
||||||
if ( ent->dentry )
|
if (ent->dentry)
|
||||||
dput(ent->dentry);
|
dput(ent->dentry);
|
||||||
kfree(ent->name);
|
kfree(ent->name);
|
||||||
kfree(ent);
|
kfree(ent);
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
#
|
|
||||||
# B.A.T.M.A.N meshing protocol
|
|
||||||
#
|
|
||||||
|
|
||||||
config BATMAN_ADV
|
|
||||||
tristate "B.A.T.M.A.N. Advanced Meshing Protocol"
|
|
||||||
depends on NET
|
|
||||||
default n
|
|
||||||
---help---
|
|
||||||
|
|
||||||
B.A.T.M.A.N. (better approach to mobile ad-hoc networking) is
|
|
||||||
a routing protocol for multi-hop ad-hoc mesh networks. The
|
|
||||||
networks may be wired or wireless. See
|
|
||||||
http://www.open-mesh.org/ for more information and user space
|
|
||||||
tools.
|
|
||||||
|
|
||||||
config BATMAN_ADV_DEBUG
|
|
||||||
bool "B.A.T.M.A.N. debugging"
|
|
||||||
depends on BATMAN_ADV != n
|
|
||||||
---help---
|
|
||||||
|
|
||||||
This is an option for use by developers; most people should
|
|
||||||
say N here. This enables compilation of support for
|
|
||||||
outputting debugging information to the kernel log. The
|
|
||||||
output is controlled via the module parameter debug.
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
|||||||
#
|
|
||||||
# Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
|
|
||||||
#
|
|
||||||
# Marek Lindner, Simon Wunderlich
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or
|
|
||||||
# modify it under the terms of version 2 of the GNU General Public
|
|
||||||
# License as published by the Free Software Foundation.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
# General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software
|
|
||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
||||||
# 02110-1301, USA
|
|
||||||
#
|
|
||||||
|
|
||||||
obj-$(CONFIG_BATMAN_ADV) += batman-adv.o
|
|
||||||
batman-adv-y := main.o bat_debugfs.o bat_sysfs.o send.o routing.o soft-interface.o icmp_socket.o translation-table.o bitarray.o hash.o ring_buffer.o vis.o hard-interface.o aggregation.o originator.o unicast.o
|
|
@ -1,240 +0,0 @@
|
|||||||
[state: 04-09-2010]
|
|
||||||
|
|
||||||
BATMAN-ADV
|
|
||||||
----------
|
|
||||||
|
|
||||||
Batman advanced is a new approach to wireless networking which
|
|
||||||
does no longer operate on the IP basis. Unlike the batman daemon,
|
|
||||||
which exchanges information using UDP packets and sets routing
|
|
||||||
tables, batman-advanced operates on ISO/OSI Layer 2 only and uses
|
|
||||||
and routes (or better: bridges) Ethernet Frames. It emulates a
|
|
||||||
virtual network switch of all nodes participating. Therefore all
|
|
||||||
nodes appear to be link local, thus all higher operating proto-
|
|
||||||
cols won't be affected by any changes within the network. You can
|
|
||||||
run almost any protocol above batman advanced, prominent examples
|
|
||||||
are: IPv4, IPv6, DHCP, IPX.
|
|
||||||
|
|
||||||
Batman advanced was implemented as a Linux kernel driver to re-
|
|
||||||
duce the overhead to a minimum. It does not depend on any (other)
|
|
||||||
network driver, and can be used on wifi as well as ethernet lan,
|
|
||||||
vpn, etc ... (anything with ethernet-style layer 2).
|
|
||||||
|
|
||||||
CONFIGURATION
|
|
||||||
-------------
|
|
||||||
|
|
||||||
Load the batman-adv module into your kernel:
|
|
||||||
|
|
||||||
# insmod batman-adv.ko
|
|
||||||
|
|
||||||
The module is now waiting for activation. You must add some in-
|
|
||||||
terfaces on which batman can operate. After loading the module
|
|
||||||
batman advanced will scan your systems interfaces to search for
|
|
||||||
compatible interfaces. Once found, it will create subfolders in
|
|
||||||
the /sys directories of each supported interface, e.g.
|
|
||||||
|
|
||||||
# ls /sys/class/net/eth0/batman_adv/
|
|
||||||
# iface_status mesh_iface
|
|
||||||
|
|
||||||
If an interface does not have the "batman_adv" subfolder it prob-
|
|
||||||
ably is not supported. Not supported interfaces are: loopback,
|
|
||||||
non-ethernet and batman's own interfaces.
|
|
||||||
|
|
||||||
Note: After the module was loaded it will continuously watch for
|
|
||||||
new interfaces to verify the compatibility. There is no need to
|
|
||||||
reload the module if you plug your USB wifi adapter into your ma-
|
|
||||||
chine after batman advanced was initially loaded.
|
|
||||||
|
|
||||||
To activate a given interface simply write "bat0" into its
|
|
||||||
"mesh_iface" file inside the batman_adv subfolder:
|
|
||||||
|
|
||||||
# echo bat0 > /sys/class/net/eth0/batman_adv/mesh_iface
|
|
||||||
|
|
||||||
Repeat this step for all interfaces you wish to add. Now batman
|
|
||||||
starts using/broadcasting on this/these interface(s).
|
|
||||||
|
|
||||||
By reading the "iface_status" file you can check its status:
|
|
||||||
|
|
||||||
# cat /sys/class/net/eth0/batman_adv/iface_status
|
|
||||||
# active
|
|
||||||
|
|
||||||
To deactivate an interface you have to write "none" into its
|
|
||||||
"mesh_iface" file:
|
|
||||||
|
|
||||||
# echo none > /sys/class/net/eth0/batman_adv/mesh_iface
|
|
||||||
|
|
||||||
|
|
||||||
All mesh wide settings can be found in batman's own interface
|
|
||||||
folder:
|
|
||||||
|
|
||||||
# ls /sys/class/net/bat0/mesh/
|
|
||||||
# aggregated_ogms bonding orig_interval vis_mode
|
|
||||||
|
|
||||||
|
|
||||||
There is a special folder for debugging informations:
|
|
||||||
|
|
||||||
# ls /sys/kernel/debug/batman_adv/bat0/
|
|
||||||
# originators socket transtable_global transtable_local
|
|
||||||
# vis_data
|
|
||||||
|
|
||||||
|
|
||||||
Some of the files contain all sort of status information regard-
|
|
||||||
ing the mesh network. For example, you can view the table of
|
|
||||||
originators (mesh participants) with:
|
|
||||||
|
|
||||||
# cat /sys/kernel/debug/batman_adv/bat0/originators
|
|
||||||
|
|
||||||
Other files allow to change batman's behaviour to better fit your
|
|
||||||
requirements. For instance, you can check the current originator
|
|
||||||
interval (value in milliseconds which determines how often batman
|
|
||||||
sends its broadcast packets):
|
|
||||||
|
|
||||||
# cat /sys/class/net/bat0/mesh/orig_interval
|
|
||||||
# 1000
|
|
||||||
|
|
||||||
and also change its value:
|
|
||||||
|
|
||||||
# echo 3000 > /sys/class/net/bat0/mesh/orig_interval
|
|
||||||
|
|
||||||
In very mobile scenarios, you might want to adjust the originator
|
|
||||||
interval to a lower value. This will make the mesh more respon-
|
|
||||||
sive to topology changes, but will also increase the overhead.
|
|
||||||
|
|
||||||
|
|
||||||
USAGE
|
|
||||||
-----
|
|
||||||
|
|
||||||
To make use of your newly created mesh, batman advanced provides
|
|
||||||
a new interface "bat0" which you should use from this point on.
|
|
||||||
All interfaces added to batman advanced are not relevant any
|
|
||||||
longer because batman handles them for you. Basically, one "hands
|
|
||||||
over" the data by using the batman interface and batman will make
|
|
||||||
sure it reaches its destination.
|
|
||||||
|
|
||||||
The "bat0" interface can be used like any other regular inter-
|
|
||||||
face. It needs an IP address which can be either statically con-
|
|
||||||
figured or dynamically (by using DHCP or similar services):
|
|
||||||
|
|
||||||
# NodeA: ifconfig bat0 192.168.0.1
|
|
||||||
# NodeB: ifconfig bat0 192.168.0.2
|
|
||||||
# NodeB: ping 192.168.0.1
|
|
||||||
|
|
||||||
Note: In order to avoid problems remove all IP addresses previ-
|
|
||||||
ously assigned to interfaces now used by batman advanced, e.g.
|
|
||||||
|
|
||||||
# ifconfig eth0 0.0.0.0
|
|
||||||
|
|
||||||
|
|
||||||
VISUALIZATION
|
|
||||||
-------------
|
|
||||||
|
|
||||||
If you want topology visualization, at least one mesh node must
|
|
||||||
be configured as VIS-server:
|
|
||||||
|
|
||||||
# echo "server" > /sys/class/net/bat0/mesh/vis_mode
|
|
||||||
|
|
||||||
Each node is either configured as "server" or as "client" (de-
|
|
||||||
fault: "client"). Clients send their topology data to the server
|
|
||||||
next to them, and server synchronize with other servers. If there
|
|
||||||
is no server configured (default) within the mesh, no topology
|
|
||||||
information will be transmitted. With these "synchronizing
|
|
||||||
servers", there can be 1 or more vis servers sharing the same (or
|
|
||||||
at least very similar) data.
|
|
||||||
|
|
||||||
When configured as server, you can get a topology snapshot of
|
|
||||||
your mesh:
|
|
||||||
|
|
||||||
# cat /sys/kernel/debug/batman_adv/bat0/vis_data
|
|
||||||
|
|
||||||
This raw output is intended to be easily parsable and convertable
|
|
||||||
with other tools. Have a look at the batctl README if you want a
|
|
||||||
vis output in dot or json format for instance and how those out-
|
|
||||||
puts could then be visualised in an image.
|
|
||||||
|
|
||||||
The raw format consists of comma separated values per entry where
|
|
||||||
each entry is giving information about a certain source inter-
|
|
||||||
face. Each entry can/has to have the following values:
|
|
||||||
-> "mac" - mac address of an originator's source interface
|
|
||||||
(each line begins with it)
|
|
||||||
-> "TQ mac value" - src mac's link quality towards mac address
|
|
||||||
of a neighbor originator's interface which
|
|
||||||
is being used for routing
|
|
||||||
-> "HNA mac" - HNA announced by source mac
|
|
||||||
-> "PRIMARY" - this is a primary interface
|
|
||||||
-> "SEC mac" - secondary mac address of source
|
|
||||||
(requires preceding PRIMARY)
|
|
||||||
|
|
||||||
The TQ value has a range from 4 to 255 with 255 being the best.
|
|
||||||
The HNA entries are showing which hosts are connected to the mesh
|
|
||||||
via bat0 or being bridged into the mesh network. The PRIMARY/SEC
|
|
||||||
values are only applied on primary interfaces
|
|
||||||
|
|
||||||
|
|
||||||
LOGGING/DEBUGGING
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
All error messages, warnings and information messages are sent to
|
|
||||||
the kernel log. Depending on your operating system distribution
|
|
||||||
this can be read in one of a number of ways. Try using the com-
|
|
||||||
mands: dmesg, logread, or looking in the files /var/log/kern.log
|
|
||||||
or /var/log/syslog. All batman-adv messages are prefixed with
|
|
||||||
"batman-adv:" So to see just these messages try
|
|
||||||
|
|
||||||
# dmesg | grep batman-adv
|
|
||||||
|
|
||||||
When investigating problems with your mesh network it is some-
|
|
||||||
times necessary to see more detail debug messages. This must be
|
|
||||||
enabled when compiling the batman-adv module. When building bat-
|
|
||||||
man-adv as part of kernel, use "make menuconfig" and enable the
|
|
||||||
option "B.A.T.M.A.N. debugging".
|
|
||||||
|
|
||||||
Those additional debug messages can be accessed using a special
|
|
||||||
file in debugfs
|
|
||||||
|
|
||||||
# cat /sys/kernel/debug/batman_adv/bat0/log
|
|
||||||
|
|
||||||
The additional debug output is by default disabled. It can be en-
|
|
||||||
abled during run time. Following log_levels are defined:
|
|
||||||
|
|
||||||
0 - All debug output disabled
|
|
||||||
1 - Enable messages related to routing / flooding / broadcasting
|
|
||||||
2 - Enable route or hna added / changed / deleted
|
|
||||||
3 - Enable all messages
|
|
||||||
|
|
||||||
The debug output can be changed at runtime using the file
|
|
||||||
/sys/class/net/bat0/mesh/log_level. e.g.
|
|
||||||
|
|
||||||
# echo 2 > /sys/class/net/bat0/mesh/log_level
|
|
||||||
|
|
||||||
will enable debug messages for when routes or HNAs change.
|
|
||||||
|
|
||||||
|
|
||||||
BATCTL
|
|
||||||
------
|
|
||||||
|
|
||||||
As batman advanced operates on layer 2 all hosts participating in
|
|
||||||
the virtual switch are completely transparent for all protocols
|
|
||||||
above layer 2. Therefore the common diagnosis tools do not work
|
|
||||||
as expected. To overcome these problems batctl was created. At
|
|
||||||
the moment the batctl contains ping, traceroute, tcpdump and
|
|
||||||
interfaces to the kernel module settings.
|
|
||||||
|
|
||||||
For more information, please see the manpage (man batctl).
|
|
||||||
|
|
||||||
batctl is available on http://www.open-mesh.org/
|
|
||||||
|
|
||||||
|
|
||||||
CONTACT
|
|
||||||
-------
|
|
||||||
|
|
||||||
Please send us comments, experiences, questions, anything :)
|
|
||||||
|
|
||||||
IRC: #batman on irc.freenode.org
|
|
||||||
Mailing-list: b.a.t.m.a.n@b.a.t.m.a.n@lists.open-mesh.org
|
|
||||||
(optional subscription at
|
|
||||||
https://lists.open-mesh.org/mm/listinfo/b.a.t.m.a.n)
|
|
||||||
|
|
||||||
You can also contact the Authors:
|
|
||||||
|
|
||||||
Marek Lindner <lindner_marek@yahoo.de>
|
|
||||||
Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
|||||||
* remove own list functionality from hash
|
|
||||||
* use hlist_head, hlist_node in hash
|
|
||||||
* don't use callbacks for compare+choose in hash
|
|
||||||
* think about more efficient ways instead of abstraction of hash
|
|
||||||
* Request a new review
|
|
||||||
* Process the comments from the review
|
|
||||||
* Move into mainline proper
|
|
||||||
|
|
||||||
Please send all patches to:
|
|
||||||
Marek Lindner <lindner_marek@yahoo.de>
|
|
||||||
Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
|
|
||||||
Andrew Lunn <andrew@lunn.ch>
|
|
||||||
b.a.t.m.a.n@lists.open-mesh.org
|
|
||||||
Greg Kroah-Hartman <gregkh@suse.de>
|
|
@ -1,275 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
|
|
||||||
*
|
|
||||||
* Marek Lindner, Simon Wunderlich
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of version 2 of the GNU General Public
|
|
||||||
* License as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
||||||
* 02110-1301, USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "main.h"
|
|
||||||
#include "aggregation.h"
|
|
||||||
#include "send.h"
|
|
||||||
#include "routing.h"
|
|
||||||
|
|
||||||
/* calculate the size of the hna information for a given packet */
|
|
||||||
static int hna_len(struct batman_packet *batman_packet)
|
|
||||||
{
|
|
||||||
return batman_packet->num_hna * ETH_ALEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* return true if new_packet can be aggregated with forw_packet */
|
|
||||||
static bool can_aggregate_with(struct batman_packet *new_batman_packet,
|
|
||||||
int packet_len,
|
|
||||||
unsigned long send_time,
|
|
||||||
bool directlink,
|
|
||||||
struct batman_if *if_incoming,
|
|
||||||
struct forw_packet *forw_packet)
|
|
||||||
{
|
|
||||||
struct batman_packet *batman_packet =
|
|
||||||
(struct batman_packet *)forw_packet->skb->data;
|
|
||||||
int aggregated_bytes = forw_packet->packet_len + packet_len;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* we can aggregate the current packet to this aggregated packet
|
|
||||||
* if:
|
|
||||||
*
|
|
||||||
* - the send time is within our MAX_AGGREGATION_MS time
|
|
||||||
* - the resulting packet wont be bigger than
|
|
||||||
* MAX_AGGREGATION_BYTES
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (time_before(send_time, forw_packet->send_time) &&
|
|
||||||
time_after_eq(send_time + msecs_to_jiffies(MAX_AGGREGATION_MS),
|
|
||||||
forw_packet->send_time) &&
|
|
||||||
(aggregated_bytes <= MAX_AGGREGATION_BYTES)) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* check aggregation compatibility
|
|
||||||
* -> direct link packets are broadcasted on
|
|
||||||
* their interface only
|
|
||||||
* -> aggregate packet if the current packet is
|
|
||||||
* a "global" packet as well as the base
|
|
||||||
* packet
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* packets without direct link flag and high TTL
|
|
||||||
* are flooded through the net */
|
|
||||||
if ((!directlink) &&
|
|
||||||
(!(batman_packet->flags & DIRECTLINK)) &&
|
|
||||||
(batman_packet->ttl != 1) &&
|
|
||||||
|
|
||||||
/* own packets originating non-primary
|
|
||||||
* interfaces leave only that interface */
|
|
||||||
((!forw_packet->own) ||
|
|
||||||
(forw_packet->if_incoming->if_num == 0)))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
/* if the incoming packet is sent via this one
|
|
||||||
* interface only - we still can aggregate */
|
|
||||||
if ((directlink) &&
|
|
||||||
(new_batman_packet->ttl == 1) &&
|
|
||||||
(forw_packet->if_incoming == if_incoming) &&
|
|
||||||
|
|
||||||
/* packets from direct neighbors or
|
|
||||||
* own secondary interface packets
|
|
||||||
* (= secondary interface packets in general) */
|
|
||||||
(batman_packet->flags & DIRECTLINK ||
|
|
||||||
(forw_packet->own &&
|
|
||||||
forw_packet->if_incoming->if_num != 0)))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0)
|
|
||||||
/* create a new aggregated packet and add this packet to it */
|
|
||||||
static void new_aggregated_packet(unsigned char *packet_buff, int packet_len,
|
|
||||||
unsigned long send_time, bool direct_link,
|
|
||||||
struct batman_if *if_incoming,
|
|
||||||
int own_packet)
|
|
||||||
{
|
|
||||||
struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
|
|
||||||
struct forw_packet *forw_packet_aggr;
|
|
||||||
unsigned long flags;
|
|
||||||
unsigned char *skb_buff;
|
|
||||||
|
|
||||||
/* own packet should always be scheduled */
|
|
||||||
if (!own_packet) {
|
|
||||||
if (!atomic_dec_not_zero(&bat_priv->batman_queue_left)) {
|
|
||||||
bat_dbg(DBG_BATMAN, bat_priv,
|
|
||||||
"batman packet queue full\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
forw_packet_aggr = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC);
|
|
||||||
if (!forw_packet_aggr) {
|
|
||||||
if (!own_packet)
|
|
||||||
atomic_inc(&bat_priv->batman_queue_left);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((atomic_read(&bat_priv->aggregation_enabled)) &&
|
|
||||||
(packet_len < MAX_AGGREGATION_BYTES))
|
|
||||||
forw_packet_aggr->skb = dev_alloc_skb(MAX_AGGREGATION_BYTES +
|
|
||||||
sizeof(struct ethhdr));
|
|
||||||
else
|
|
||||||
forw_packet_aggr->skb = dev_alloc_skb(packet_len +
|
|
||||||
sizeof(struct ethhdr));
|
|
||||||
|
|
||||||
if (!forw_packet_aggr->skb) {
|
|
||||||
if (!own_packet)
|
|
||||||
atomic_inc(&bat_priv->batman_queue_left);
|
|
||||||
kfree(forw_packet_aggr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
skb_reserve(forw_packet_aggr->skb, sizeof(struct ethhdr));
|
|
||||||
|
|
||||||
INIT_HLIST_NODE(&forw_packet_aggr->list);
|
|
||||||
|
|
||||||
skb_buff = skb_put(forw_packet_aggr->skb, packet_len);
|
|
||||||
forw_packet_aggr->packet_len = packet_len;
|
|
||||||
memcpy(skb_buff, packet_buff, packet_len);
|
|
||||||
|
|
||||||
forw_packet_aggr->own = own_packet;
|
|
||||||
forw_packet_aggr->if_incoming = if_incoming;
|
|
||||||
forw_packet_aggr->num_packets = 0;
|
|
||||||
forw_packet_aggr->direct_link_flags = 0;
|
|
||||||
forw_packet_aggr->send_time = send_time;
|
|
||||||
|
|
||||||
/* save packet direct link flag status */
|
|
||||||
if (direct_link)
|
|
||||||
forw_packet_aggr->direct_link_flags |= 1;
|
|
||||||
|
|
||||||
/* add new packet to packet list */
|
|
||||||
spin_lock_irqsave(&bat_priv->forw_bat_list_lock, flags);
|
|
||||||
hlist_add_head(&forw_packet_aggr->list, &bat_priv->forw_bat_list);
|
|
||||||
spin_unlock_irqrestore(&bat_priv->forw_bat_list_lock, flags);
|
|
||||||
|
|
||||||
/* start timer for this packet */
|
|
||||||
INIT_DELAYED_WORK(&forw_packet_aggr->delayed_work,
|
|
||||||
send_outstanding_bat_packet);
|
|
||||||
queue_delayed_work(bat_event_workqueue,
|
|
||||||
&forw_packet_aggr->delayed_work,
|
|
||||||
send_time - jiffies);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* aggregate a new packet into the existing aggregation */
|
|
||||||
static void aggregate(struct forw_packet *forw_packet_aggr,
|
|
||||||
unsigned char *packet_buff,
|
|
||||||
int packet_len,
|
|
||||||
bool direct_link)
|
|
||||||
{
|
|
||||||
unsigned char *skb_buff;
|
|
||||||
|
|
||||||
skb_buff = skb_put(forw_packet_aggr->skb, packet_len);
|
|
||||||
memcpy(skb_buff, packet_buff, packet_len);
|
|
||||||
forw_packet_aggr->packet_len += packet_len;
|
|
||||||
forw_packet_aggr->num_packets++;
|
|
||||||
|
|
||||||
/* save packet direct link flag status */
|
|
||||||
if (direct_link)
|
|
||||||
forw_packet_aggr->direct_link_flags |=
|
|
||||||
(1 << forw_packet_aggr->num_packets);
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_bat_packet_to_list(struct bat_priv *bat_priv,
|
|
||||||
unsigned char *packet_buff, int packet_len,
|
|
||||||
struct batman_if *if_incoming, char own_packet,
|
|
||||||
unsigned long send_time)
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* _aggr -> pointer to the packet we want to aggregate with
|
|
||||||
* _pos -> pointer to the position in the queue
|
|
||||||
*/
|
|
||||||
struct forw_packet *forw_packet_aggr = NULL, *forw_packet_pos = NULL;
|
|
||||||
struct hlist_node *tmp_node;
|
|
||||||
struct batman_packet *batman_packet =
|
|
||||||
(struct batman_packet *)packet_buff;
|
|
||||||
bool direct_link = batman_packet->flags & DIRECTLINK ? 1 : 0;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
/* find position for the packet in the forward queue */
|
|
||||||
spin_lock_irqsave(&bat_priv->forw_bat_list_lock, flags);
|
|
||||||
/* own packets are not to be aggregated */
|
|
||||||
if ((atomic_read(&bat_priv->aggregation_enabled)) && (!own_packet)) {
|
|
||||||
hlist_for_each_entry(forw_packet_pos, tmp_node,
|
|
||||||
&bat_priv->forw_bat_list, list) {
|
|
||||||
if (can_aggregate_with(batman_packet,
|
|
||||||
packet_len,
|
|
||||||
send_time,
|
|
||||||
direct_link,
|
|
||||||
if_incoming,
|
|
||||||
forw_packet_pos)) {
|
|
||||||
forw_packet_aggr = forw_packet_pos;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* nothing to aggregate with - either aggregation disabled or no
|
|
||||||
* suitable aggregation packet found */
|
|
||||||
if (forw_packet_aggr == NULL) {
|
|
||||||
/* the following section can run without the lock */
|
|
||||||
spin_unlock_irqrestore(&bat_priv->forw_bat_list_lock, flags);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* if we could not aggregate this packet with one of the others
|
|
||||||
* we hold it back for a while, so that it might be aggregated
|
|
||||||
* later on
|
|
||||||
*/
|
|
||||||
if ((!own_packet) &&
|
|
||||||
(atomic_read(&bat_priv->aggregation_enabled)))
|
|
||||||
send_time += msecs_to_jiffies(MAX_AGGREGATION_MS);
|
|
||||||
|
|
||||||
new_aggregated_packet(packet_buff, packet_len,
|
|
||||||
send_time, direct_link,
|
|
||||||
if_incoming, own_packet);
|
|
||||||
} else {
|
|
||||||
aggregate(forw_packet_aggr,
|
|
||||||
packet_buff, packet_len,
|
|
||||||
direct_link);
|
|
||||||
spin_unlock_irqrestore(&bat_priv->forw_bat_list_lock, flags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* unpack the aggregated packets and process them one by one */
|
|
||||||
void receive_aggr_bat_packet(struct ethhdr *ethhdr, unsigned char *packet_buff,
|
|
||||||
int packet_len, struct batman_if *if_incoming)
|
|
||||||
{
|
|
||||||
struct batman_packet *batman_packet;
|
|
||||||
int buff_pos = 0;
|
|
||||||
unsigned char *hna_buff;
|
|
||||||
|
|
||||||
batman_packet = (struct batman_packet *)packet_buff;
|
|
||||||
|
|
||||||
do {
|
|
||||||
/* network to host order for our 32bit seqno, and the
|
|
||||||
orig_interval. */
|
|
||||||
batman_packet->seqno = ntohl(batman_packet->seqno);
|
|
||||||
|
|
||||||
hna_buff = packet_buff + buff_pos + BAT_PACKET_LEN;
|
|
||||||
receive_bat_packet(ethhdr, batman_packet,
|
|
||||||
hna_buff, hna_len(batman_packet),
|
|
||||||
if_incoming);
|
|
||||||
|
|
||||||
buff_pos += BAT_PACKET_LEN + hna_len(batman_packet);
|
|
||||||
batman_packet = (struct batman_packet *)
|
|
||||||
(packet_buff + buff_pos);
|
|
||||||
} while (aggregated_packet(buff_pos, packet_len,
|
|
||||||
batman_packet->num_hna));
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
|
|
||||||
*
|
|
||||||
* Marek Lindner, Simon Wunderlich
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of version 2 of the GNU General Public
|
|
||||||
* License as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
||||||
* 02110-1301, USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _NET_BATMAN_ADV_AGGREGATION_H_
|
|
||||||
#define _NET_BATMAN_ADV_AGGREGATION_H_
|
|
||||||
|
|
||||||
#include "main.h"
|
|
||||||
|
|
||||||
/* is there another aggregated packet here? */
|
|
||||||
static inline int aggregated_packet(int buff_pos, int packet_len, int num_hna)
|
|
||||||
{
|
|
||||||
int next_buff_pos = buff_pos + BAT_PACKET_LEN + (num_hna * ETH_ALEN);
|
|
||||||
|
|
||||||
return (next_buff_pos <= packet_len) &&
|
|
||||||
(next_buff_pos <= MAX_AGGREGATION_BYTES);
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_bat_packet_to_list(struct bat_priv *bat_priv,
|
|
||||||
unsigned char *packet_buff, int packet_len,
|
|
||||||
struct batman_if *if_incoming, char own_packet,
|
|
||||||
unsigned long send_time);
|
|
||||||
void receive_aggr_bat_packet(struct ethhdr *ethhdr, unsigned char *packet_buff,
|
|
||||||
int packet_len, struct batman_if *if_incoming);
|
|
||||||
|
|
||||||
#endif /* _NET_BATMAN_ADV_AGGREGATION_H_ */
|
|
@ -1,343 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2010 B.A.T.M.A.N. contributors:
|
|
||||||
*
|
|
||||||
* Marek Lindner
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of version 2 of the GNU General Public
|
|
||||||
* License as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
||||||
* 02110-1301, USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "main.h"
|
|
||||||
|
|
||||||
#include <linux/debugfs.h>
|
|
||||||
|
|
||||||
#include "bat_debugfs.h"
|
|
||||||
#include "translation-table.h"
|
|
||||||
#include "originator.h"
|
|
||||||
#include "hard-interface.h"
|
|
||||||
#include "vis.h"
|
|
||||||
#include "icmp_socket.h"
|
|
||||||
|
|
||||||
static struct dentry *bat_debugfs;
|
|
||||||
|
|
||||||
#ifdef CONFIG_BATMAN_ADV_DEBUG
|
|
||||||
#define LOG_BUFF_MASK (log_buff_len-1)
|
|
||||||
#define LOG_BUFF(idx) (debug_log->log_buff[(idx) & LOG_BUFF_MASK])
|
|
||||||
|
|
||||||
static int log_buff_len = LOG_BUF_LEN;
|
|
||||||
|
|
||||||
static void emit_log_char(struct debug_log *debug_log, char c)
|
|
||||||
{
|
|
||||||
LOG_BUFF(debug_log->log_end) = c;
|
|
||||||
debug_log->log_end++;
|
|
||||||
|
|
||||||
if (debug_log->log_end - debug_log->log_start > log_buff_len)
|
|
||||||
debug_log->log_start = debug_log->log_end - log_buff_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int fdebug_log(struct debug_log *debug_log, char *fmt, ...)
|
|
||||||
{
|
|
||||||
int printed_len;
|
|
||||||
va_list args;
|
|
||||||
static char debug_log_buf[256];
|
|
||||||
char *p;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
if (!debug_log)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&debug_log->lock, flags);
|
|
||||||
va_start(args, fmt);
|
|
||||||
printed_len = vscnprintf(debug_log_buf, sizeof(debug_log_buf),
|
|
||||||
fmt, args);
|
|
||||||
va_end(args);
|
|
||||||
|
|
||||||
for (p = debug_log_buf; *p != 0; p++)
|
|
||||||
emit_log_char(debug_log, *p);
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&debug_log->lock, flags);
|
|
||||||
|
|
||||||
wake_up(&debug_log->queue_wait);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int debug_log(struct bat_priv *bat_priv, char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list args;
|
|
||||||
char tmp_log_buf[256];
|
|
||||||
|
|
||||||
va_start(args, fmt);
|
|
||||||
vscnprintf(tmp_log_buf, sizeof(tmp_log_buf), fmt, args);
|
|
||||||
fdebug_log(bat_priv->debug_log, "[%10u] %s",
|
|
||||||
(jiffies / HZ), tmp_log_buf);
|
|
||||||
va_end(args);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int log_open(struct inode *inode, struct file *file)
|
|
||||||
{
|
|
||||||
nonseekable_open(inode, file);
|
|
||||||
file->private_data = inode->i_private;
|
|
||||||
inc_module_count();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int log_release(struct inode *inode, struct file *file)
|
|
||||||
{
|
|
||||||
dec_module_count();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t log_read(struct file *file, char __user *buf,
|
|
||||||
size_t count, loff_t *ppos)
|
|
||||||
{
|
|
||||||
struct bat_priv *bat_priv = file->private_data;
|
|
||||||
struct debug_log *debug_log = bat_priv->debug_log;
|
|
||||||
int error, i = 0;
|
|
||||||
char c;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
if ((file->f_flags & O_NONBLOCK) &&
|
|
||||||
!(debug_log->log_end - debug_log->log_start))
|
|
||||||
return -EAGAIN;
|
|
||||||
|
|
||||||
if ((!buf) || (count < 0))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (count == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (!access_ok(VERIFY_WRITE, buf, count))
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
error = wait_event_interruptible(debug_log->queue_wait,
|
|
||||||
(debug_log->log_start - debug_log->log_end));
|
|
||||||
|
|
||||||
if (error)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&debug_log->lock, flags);
|
|
||||||
|
|
||||||
while ((!error) && (i < count) &&
|
|
||||||
(debug_log->log_start != debug_log->log_end)) {
|
|
||||||
c = LOG_BUFF(debug_log->log_start);
|
|
||||||
|
|
||||||
debug_log->log_start++;
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&debug_log->lock, flags);
|
|
||||||
|
|
||||||
error = __put_user(c, buf);
|
|
||||||
|
|
||||||
spin_lock_irqsave(&debug_log->lock, flags);
|
|
||||||
|
|
||||||
buf++;
|
|
||||||
i++;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&debug_log->lock, flags);
|
|
||||||
|
|
||||||
if (!error)
|
|
||||||
return i;
|
|
||||||
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned int log_poll(struct file *file, poll_table *wait)
|
|
||||||
{
|
|
||||||
struct bat_priv *bat_priv = file->private_data;
|
|
||||||
struct debug_log *debug_log = bat_priv->debug_log;
|
|
||||||
|
|
||||||
poll_wait(file, &debug_log->queue_wait, wait);
|
|
||||||
|
|
||||||
if (debug_log->log_end - debug_log->log_start)
|
|
||||||
return POLLIN | POLLRDNORM;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct file_operations log_fops = {
|
|
||||||
.open = log_open,
|
|
||||||
.release = log_release,
|
|
||||||
.read = log_read,
|
|
||||||
.poll = log_poll,
|
|
||||||
.llseek = no_llseek,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int debug_log_setup(struct bat_priv *bat_priv)
|
|
||||||
{
|
|
||||||
struct dentry *d;
|
|
||||||
|
|
||||||
if (!bat_priv->debug_dir)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
bat_priv->debug_log = kzalloc(sizeof(struct debug_log), GFP_ATOMIC);
|
|
||||||
if (!bat_priv->debug_log)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
spin_lock_init(&bat_priv->debug_log->lock);
|
|
||||||
init_waitqueue_head(&bat_priv->debug_log->queue_wait);
|
|
||||||
|
|
||||||
d = debugfs_create_file("log", S_IFREG | S_IRUSR,
|
|
||||||
bat_priv->debug_dir, bat_priv, &log_fops);
|
|
||||||
if (d)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
err:
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void debug_log_cleanup(struct bat_priv *bat_priv)
|
|
||||||
{
|
|
||||||
kfree(bat_priv->debug_log);
|
|
||||||
bat_priv->debug_log = NULL;
|
|
||||||
}
|
|
||||||
#else /* CONFIG_BATMAN_ADV_DEBUG */
|
|
||||||
static int debug_log_setup(struct bat_priv *bat_priv)
|
|
||||||
{
|
|
||||||
bat_priv->debug_log = NULL;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void debug_log_cleanup(struct bat_priv *bat_priv)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int originators_open(struct inode *inode, struct file *file)
|
|
||||||
{
|
|
||||||
struct net_device *net_dev = (struct net_device *)inode->i_private;
|
|
||||||
return single_open(file, orig_seq_print_text, net_dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int transtable_global_open(struct inode *inode, struct file *file)
|
|
||||||
{
|
|
||||||
struct net_device *net_dev = (struct net_device *)inode->i_private;
|
|
||||||
return single_open(file, hna_global_seq_print_text, net_dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int transtable_local_open(struct inode *inode, struct file *file)
|
|
||||||
{
|
|
||||||
struct net_device *net_dev = (struct net_device *)inode->i_private;
|
|
||||||
return single_open(file, hna_local_seq_print_text, net_dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int vis_data_open(struct inode *inode, struct file *file)
|
|
||||||
{
|
|
||||||
struct net_device *net_dev = (struct net_device *)inode->i_private;
|
|
||||||
return single_open(file, vis_seq_print_text, net_dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct bat_debuginfo {
|
|
||||||
struct attribute attr;
|
|
||||||
const struct file_operations fops;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define BAT_DEBUGINFO(_name, _mode, _open) \
|
|
||||||
struct bat_debuginfo bat_debuginfo_##_name = { \
|
|
||||||
.attr = { .name = __stringify(_name), \
|
|
||||||
.mode = _mode, }, \
|
|
||||||
.fops = { .owner = THIS_MODULE, \
|
|
||||||
.open = _open, \
|
|
||||||
.read = seq_read, \
|
|
||||||
.llseek = seq_lseek, \
|
|
||||||
.release = single_release, \
|
|
||||||
} \
|
|
||||||
};
|
|
||||||
|
|
||||||
static BAT_DEBUGINFO(originators, S_IRUGO, originators_open);
|
|
||||||
static BAT_DEBUGINFO(transtable_global, S_IRUGO, transtable_global_open);
|
|
||||||
static BAT_DEBUGINFO(transtable_local, S_IRUGO, transtable_local_open);
|
|
||||||
static BAT_DEBUGINFO(vis_data, S_IRUGO, vis_data_open);
|
|
||||||
|
|
||||||
static struct bat_debuginfo *mesh_debuginfos[] = {
|
|
||||||
&bat_debuginfo_originators,
|
|
||||||
&bat_debuginfo_transtable_global,
|
|
||||||
&bat_debuginfo_transtable_local,
|
|
||||||
&bat_debuginfo_vis_data,
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
void debugfs_init(void)
|
|
||||||
{
|
|
||||||
bat_debugfs = debugfs_create_dir(DEBUGFS_BAT_SUBDIR, NULL);
|
|
||||||
if (bat_debugfs == ERR_PTR(-ENODEV))
|
|
||||||
bat_debugfs = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void debugfs_destroy(void)
|
|
||||||
{
|
|
||||||
if (bat_debugfs) {
|
|
||||||
debugfs_remove_recursive(bat_debugfs);
|
|
||||||
bat_debugfs = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int debugfs_add_meshif(struct net_device *dev)
|
|
||||||
{
|
|
||||||
struct bat_priv *bat_priv = netdev_priv(dev);
|
|
||||||
struct bat_debuginfo **bat_debug;
|
|
||||||
struct dentry *file;
|
|
||||||
|
|
||||||
if (!bat_debugfs)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
bat_priv->debug_dir = debugfs_create_dir(dev->name, bat_debugfs);
|
|
||||||
if (!bat_priv->debug_dir)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
bat_socket_setup(bat_priv);
|
|
||||||
debug_log_setup(bat_priv);
|
|
||||||
|
|
||||||
for (bat_debug = mesh_debuginfos; *bat_debug; ++bat_debug) {
|
|
||||||
file = debugfs_create_file(((*bat_debug)->attr).name,
|
|
||||||
S_IFREG | ((*bat_debug)->attr).mode,
|
|
||||||
bat_priv->debug_dir,
|
|
||||||
dev, &(*bat_debug)->fops);
|
|
||||||
if (!file) {
|
|
||||||
bat_err(dev, "Can't add debugfs file: %s/%s\n",
|
|
||||||
dev->name, ((*bat_debug)->attr).name);
|
|
||||||
goto rem_attr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
rem_attr:
|
|
||||||
debugfs_remove_recursive(bat_priv->debug_dir);
|
|
||||||
bat_priv->debug_dir = NULL;
|
|
||||||
out:
|
|
||||||
#ifdef CONFIG_DEBUG_FS
|
|
||||||
return -ENOMEM;
|
|
||||||
#else
|
|
||||||
return 0;
|
|
||||||
#endif /* CONFIG_DEBUG_FS */
|
|
||||||
}
|
|
||||||
|
|
||||||
void debugfs_del_meshif(struct net_device *dev)
|
|
||||||
{
|
|
||||||
struct bat_priv *bat_priv = netdev_priv(dev);
|
|
||||||
|
|
||||||
debug_log_cleanup(bat_priv);
|
|
||||||
|
|
||||||
if (bat_debugfs) {
|
|
||||||
debugfs_remove_recursive(bat_priv->debug_dir);
|
|
||||||
bat_priv->debug_dir = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2010 B.A.T.M.A.N. contributors:
|
|
||||||
*
|
|
||||||
* Marek Lindner
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of version 2 of the GNU General Public
|
|
||||||
* License as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
||||||
* 02110-1301, USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _NET_BATMAN_ADV_DEBUGFS_H_
|
|
||||||
#define _NET_BATMAN_ADV_DEBUGFS_H_
|
|
||||||
|
|
||||||
#define DEBUGFS_BAT_SUBDIR "batman_adv"
|
|
||||||
|
|
||||||
void debugfs_init(void);
|
|
||||||
void debugfs_destroy(void);
|
|
||||||
int debugfs_add_meshif(struct net_device *dev);
|
|
||||||
void debugfs_del_meshif(struct net_device *dev);
|
|
||||||
|
|
||||||
#endif /* _NET_BATMAN_ADV_DEBUGFS_H_ */
|
|
@ -1,558 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2010 B.A.T.M.A.N. contributors:
|
|
||||||
*
|
|
||||||
* Marek Lindner
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of version 2 of the GNU General Public
|
|
||||||
* License as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
||||||
* 02110-1301, USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "main.h"
|
|
||||||
#include "bat_sysfs.h"
|
|
||||||
#include "translation-table.h"
|
|
||||||
#include "originator.h"
|
|
||||||
#include "hard-interface.h"
|
|
||||||
#include "vis.h"
|
|
||||||
|
|
||||||
#define to_dev(obj) container_of(obj, struct device, kobj)
|
|
||||||
|
|
||||||
#define BAT_ATTR(_name, _mode, _show, _store) \
|
|
||||||
struct bat_attribute bat_attr_##_name = { \
|
|
||||||
.attr = {.name = __stringify(_name), \
|
|
||||||
.mode = _mode }, \
|
|
||||||
.show = _show, \
|
|
||||||
.store = _store, \
|
|
||||||
};
|
|
||||||
|
|
||||||
static ssize_t show_aggr_ogms(struct kobject *kobj, struct attribute *attr,
|
|
||||||
char *buff)
|
|
||||||
{
|
|
||||||
struct device *dev = to_dev(kobj->parent);
|
|
||||||
struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev));
|
|
||||||
int aggr_status = atomic_read(&bat_priv->aggregation_enabled);
|
|
||||||
|
|
||||||
return sprintf(buff, "%s\n",
|
|
||||||
aggr_status == 0 ? "disabled" : "enabled");
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t store_aggr_ogms(struct kobject *kobj, struct attribute *attr,
|
|
||||||
char *buff, size_t count)
|
|
||||||
{
|
|
||||||
struct device *dev = to_dev(kobj->parent);
|
|
||||||
struct net_device *net_dev = to_net_dev(dev);
|
|
||||||
struct bat_priv *bat_priv = netdev_priv(net_dev);
|
|
||||||
int aggr_tmp = -1;
|
|
||||||
|
|
||||||
if (((count == 2) && (buff[0] == '1')) ||
|
|
||||||
(strncmp(buff, "enable", 6) == 0))
|
|
||||||
aggr_tmp = 1;
|
|
||||||
|
|
||||||
if (((count == 2) && (buff[0] == '0')) ||
|
|
||||||
(strncmp(buff, "disable", 7) == 0))
|
|
||||||
aggr_tmp = 0;
|
|
||||||
|
|
||||||
if (aggr_tmp < 0) {
|
|
||||||
if (buff[count - 1] == '\n')
|
|
||||||
buff[count - 1] = '\0';
|
|
||||||
|
|
||||||
bat_info(net_dev,
|
|
||||||
"Invalid parameter for 'aggregate OGM' setting"
|
|
||||||
"received: %s\n", buff);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (atomic_read(&bat_priv->aggregation_enabled) == aggr_tmp)
|
|
||||||
return count;
|
|
||||||
|
|
||||||
bat_info(net_dev, "Changing aggregation from: %s to: %s\n",
|
|
||||||
atomic_read(&bat_priv->aggregation_enabled) == 1 ?
|
|
||||||
"enabled" : "disabled", aggr_tmp == 1 ? "enabled" :
|
|
||||||
"disabled");
|
|
||||||
|
|
||||||
atomic_set(&bat_priv->aggregation_enabled, (unsigned)aggr_tmp);
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t show_bond(struct kobject *kobj, struct attribute *attr,
|
|
||||||
char *buff)
|
|
||||||
{
|
|
||||||
struct device *dev = to_dev(kobj->parent);
|
|
||||||
struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev));
|
|
||||||
int bond_status = atomic_read(&bat_priv->bonding_enabled);
|
|
||||||
|
|
||||||
return sprintf(buff, "%s\n",
|
|
||||||
bond_status == 0 ? "disabled" : "enabled");
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t store_bond(struct kobject *kobj, struct attribute *attr,
|
|
||||||
char *buff, size_t count)
|
|
||||||
{
|
|
||||||
struct device *dev = to_dev(kobj->parent);
|
|
||||||
struct net_device *net_dev = to_net_dev(dev);
|
|
||||||
struct bat_priv *bat_priv = netdev_priv(net_dev);
|
|
||||||
int bonding_enabled_tmp = -1;
|
|
||||||
|
|
||||||
if (((count == 2) && (buff[0] == '1')) ||
|
|
||||||
(strncmp(buff, "enable", 6) == 0))
|
|
||||||
bonding_enabled_tmp = 1;
|
|
||||||
|
|
||||||
if (((count == 2) && (buff[0] == '0')) ||
|
|
||||||
(strncmp(buff, "disable", 7) == 0))
|
|
||||||
bonding_enabled_tmp = 0;
|
|
||||||
|
|
||||||
if (bonding_enabled_tmp < 0) {
|
|
||||||
if (buff[count - 1] == '\n')
|
|
||||||
buff[count - 1] = '\0';
|
|
||||||
|
|
||||||
bat_err(net_dev,
|
|
||||||
"Invalid parameter for 'bonding' setting received: "
|
|
||||||
"%s\n", buff);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (atomic_read(&bat_priv->bonding_enabled) == bonding_enabled_tmp)
|
|
||||||
return count;
|
|
||||||
|
|
||||||
bat_info(net_dev, "Changing bonding from: %s to: %s\n",
|
|
||||||
atomic_read(&bat_priv->bonding_enabled) == 1 ?
|
|
||||||
"enabled" : "disabled",
|
|
||||||
bonding_enabled_tmp == 1 ? "enabled" : "disabled");
|
|
||||||
|
|
||||||
atomic_set(&bat_priv->bonding_enabled, (unsigned)bonding_enabled_tmp);
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t show_frag(struct kobject *kobj, struct attribute *attr,
|
|
||||||
char *buff)
|
|
||||||
{
|
|
||||||
struct device *dev = to_dev(kobj->parent);
|
|
||||||
struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev));
|
|
||||||
int frag_status = atomic_read(&bat_priv->frag_enabled);
|
|
||||||
|
|
||||||
return sprintf(buff, "%s\n",
|
|
||||||
frag_status == 0 ? "disabled" : "enabled");
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t store_frag(struct kobject *kobj, struct attribute *attr,
|
|
||||||
char *buff, size_t count)
|
|
||||||
{
|
|
||||||
struct device *dev = to_dev(kobj->parent);
|
|
||||||
struct net_device *net_dev = to_net_dev(dev);
|
|
||||||
struct bat_priv *bat_priv = netdev_priv(net_dev);
|
|
||||||
int frag_enabled_tmp = -1;
|
|
||||||
|
|
||||||
if (((count == 2) && (buff[0] == '1')) ||
|
|
||||||
(strncmp(buff, "enable", 6) == 0))
|
|
||||||
frag_enabled_tmp = 1;
|
|
||||||
|
|
||||||
if (((count == 2) && (buff[0] == '0')) ||
|
|
||||||
(strncmp(buff, "disable", 7) == 0))
|
|
||||||
frag_enabled_tmp = 0;
|
|
||||||
|
|
||||||
if (frag_enabled_tmp < 0) {
|
|
||||||
if (buff[count - 1] == '\n')
|
|
||||||
buff[count - 1] = '\0';
|
|
||||||
|
|
||||||
bat_err(net_dev,
|
|
||||||
"Invalid parameter for 'fragmentation' setting on mesh"
|
|
||||||
"received: %s\n", buff);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (atomic_read(&bat_priv->frag_enabled) == frag_enabled_tmp)
|
|
||||||
return count;
|
|
||||||
|
|
||||||
bat_info(net_dev, "Changing fragmentation from: %s to: %s\n",
|
|
||||||
atomic_read(&bat_priv->frag_enabled) == 1 ?
|
|
||||||
"enabled" : "disabled",
|
|
||||||
frag_enabled_tmp == 1 ? "enabled" : "disabled");
|
|
||||||
|
|
||||||
atomic_set(&bat_priv->frag_enabled, (unsigned)frag_enabled_tmp);
|
|
||||||
update_min_mtu(net_dev);
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t show_vis_mode(struct kobject *kobj, struct attribute *attr,
|
|
||||||
char *buff)
|
|
||||||
{
|
|
||||||
struct device *dev = to_dev(kobj->parent);
|
|
||||||
struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev));
|
|
||||||
int vis_mode = atomic_read(&bat_priv->vis_mode);
|
|
||||||
|
|
||||||
return sprintf(buff, "%s\n",
|
|
||||||
vis_mode == VIS_TYPE_CLIENT_UPDATE ?
|
|
||||||
"client" : "server");
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t store_vis_mode(struct kobject *kobj, struct attribute *attr,
|
|
||||||
char *buff, size_t count)
|
|
||||||
{
|
|
||||||
struct device *dev = to_dev(kobj->parent);
|
|
||||||
struct net_device *net_dev = to_net_dev(dev);
|
|
||||||
struct bat_priv *bat_priv = netdev_priv(net_dev);
|
|
||||||
unsigned long val;
|
|
||||||
int ret, vis_mode_tmp = -1;
|
|
||||||
|
|
||||||
ret = strict_strtoul(buff, 10, &val);
|
|
||||||
|
|
||||||
if (((count == 2) && (!ret) && (val == VIS_TYPE_CLIENT_UPDATE)) ||
|
|
||||||
(strncmp(buff, "client", 6) == 0) ||
|
|
||||||
(strncmp(buff, "off", 3) == 0))
|
|
||||||
vis_mode_tmp = VIS_TYPE_CLIENT_UPDATE;
|
|
||||||
|
|
||||||
if (((count == 2) && (!ret) && (val == VIS_TYPE_SERVER_SYNC)) ||
|
|
||||||
(strncmp(buff, "server", 6) == 0))
|
|
||||||
vis_mode_tmp = VIS_TYPE_SERVER_SYNC;
|
|
||||||
|
|
||||||
if (vis_mode_tmp < 0) {
|
|
||||||
if (buff[count - 1] == '\n')
|
|
||||||
buff[count - 1] = '\0';
|
|
||||||
|
|
||||||
bat_info(net_dev,
|
|
||||||
"Invalid parameter for 'vis mode' setting received: "
|
|
||||||
"%s\n", buff);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (atomic_read(&bat_priv->vis_mode) == vis_mode_tmp)
|
|
||||||
return count;
|
|
||||||
|
|
||||||
bat_info(net_dev, "Changing vis mode from: %s to: %s\n",
|
|
||||||
atomic_read(&bat_priv->vis_mode) == VIS_TYPE_CLIENT_UPDATE ?
|
|
||||||
"client" : "server", vis_mode_tmp == VIS_TYPE_CLIENT_UPDATE ?
|
|
||||||
"client" : "server");
|
|
||||||
|
|
||||||
atomic_set(&bat_priv->vis_mode, (unsigned)vis_mode_tmp);
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t show_orig_interval(struct kobject *kobj, struct attribute *attr,
|
|
||||||
char *buff)
|
|
||||||
{
|
|
||||||
struct device *dev = to_dev(kobj->parent);
|
|
||||||
struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev));
|
|
||||||
|
|
||||||
return sprintf(buff, "%i\n",
|
|
||||||
atomic_read(&bat_priv->orig_interval));
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t store_orig_interval(struct kobject *kobj, struct attribute *attr,
|
|
||||||
char *buff, size_t count)
|
|
||||||
{
|
|
||||||
struct device *dev = to_dev(kobj->parent);
|
|
||||||
struct net_device *net_dev = to_net_dev(dev);
|
|
||||||
struct bat_priv *bat_priv = netdev_priv(net_dev);
|
|
||||||
unsigned long orig_interval_tmp;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = strict_strtoul(buff, 10, &orig_interval_tmp);
|
|
||||||
if (ret) {
|
|
||||||
bat_info(net_dev, "Invalid parameter for 'orig_interval' "
|
|
||||||
"setting received: %s\n", buff);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (orig_interval_tmp < JITTER * 2) {
|
|
||||||
bat_info(net_dev, "New originator interval too small: %li "
|
|
||||||
"(min: %i)\n", orig_interval_tmp, JITTER * 2);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (atomic_read(&bat_priv->orig_interval) == orig_interval_tmp)
|
|
||||||
return count;
|
|
||||||
|
|
||||||
bat_info(net_dev, "Changing originator interval from: %i to: %li\n",
|
|
||||||
atomic_read(&bat_priv->orig_interval),
|
|
||||||
orig_interval_tmp);
|
|
||||||
|
|
||||||
atomic_set(&bat_priv->orig_interval, orig_interval_tmp);
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_BATMAN_ADV_DEBUG
|
|
||||||
static ssize_t show_log_level(struct kobject *kobj, struct attribute *attr,
|
|
||||||
char *buff)
|
|
||||||
{
|
|
||||||
struct device *dev = to_dev(kobj->parent);
|
|
||||||
struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev));
|
|
||||||
int log_level = atomic_read(&bat_priv->log_level);
|
|
||||||
|
|
||||||
return sprintf(buff, "%d\n", log_level);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t store_log_level(struct kobject *kobj, struct attribute *attr,
|
|
||||||
char *buff, size_t count)
|
|
||||||
{
|
|
||||||
struct device *dev = to_dev(kobj->parent);
|
|
||||||
struct net_device *net_dev = to_net_dev(dev);
|
|
||||||
struct bat_priv *bat_priv = netdev_priv(net_dev);
|
|
||||||
unsigned long log_level_tmp;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = strict_strtoul(buff, 10, &log_level_tmp);
|
|
||||||
if (ret) {
|
|
||||||
bat_info(net_dev, "Invalid parameter for 'log_level' "
|
|
||||||
"setting received: %s\n", buff);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (log_level_tmp > 3) {
|
|
||||||
bat_info(net_dev, "New log level too big: %li "
|
|
||||||
"(max: %i)\n", log_level_tmp, 3);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (atomic_read(&bat_priv->log_level) == log_level_tmp)
|
|
||||||
return count;
|
|
||||||
|
|
||||||
bat_info(net_dev, "Changing log level from: %i to: %li\n",
|
|
||||||
atomic_read(&bat_priv->log_level),
|
|
||||||
log_level_tmp);
|
|
||||||
|
|
||||||
atomic_set(&bat_priv->log_level, (unsigned)log_level_tmp);
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static BAT_ATTR(aggregated_ogms, S_IRUGO | S_IWUSR,
|
|
||||||
show_aggr_ogms, store_aggr_ogms);
|
|
||||||
static BAT_ATTR(bonding, S_IRUGO | S_IWUSR, show_bond, store_bond);
|
|
||||||
static BAT_ATTR(fragmentation, S_IRUGO | S_IWUSR, show_frag, store_frag);
|
|
||||||
static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode);
|
|
||||||
static BAT_ATTR(orig_interval, S_IRUGO | S_IWUSR,
|
|
||||||
show_orig_interval, store_orig_interval);
|
|
||||||
#ifdef CONFIG_BATMAN_ADV_DEBUG
|
|
||||||
static BAT_ATTR(log_level, S_IRUGO | S_IWUSR, show_log_level, store_log_level);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static struct bat_attribute *mesh_attrs[] = {
|
|
||||||
&bat_attr_aggregated_ogms,
|
|
||||||
&bat_attr_bonding,
|
|
||||||
&bat_attr_fragmentation,
|
|
||||||
&bat_attr_vis_mode,
|
|
||||||
&bat_attr_orig_interval,
|
|
||||||
#ifdef CONFIG_BATMAN_ADV_DEBUG
|
|
||||||
&bat_attr_log_level,
|
|
||||||
#endif
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
int sysfs_add_meshif(struct net_device *dev)
|
|
||||||
{
|
|
||||||
struct kobject *batif_kobject = &dev->dev.kobj;
|
|
||||||
struct bat_priv *bat_priv = netdev_priv(dev);
|
|
||||||
struct bat_attribute **bat_attr;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
bat_priv->mesh_obj = kobject_create_and_add(SYSFS_IF_MESH_SUBDIR,
|
|
||||||
batif_kobject);
|
|
||||||
if (!bat_priv->mesh_obj) {
|
|
||||||
bat_err(dev, "Can't add sysfs directory: %s/%s\n", dev->name,
|
|
||||||
SYSFS_IF_MESH_SUBDIR);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr) {
|
|
||||||
err = sysfs_create_file(bat_priv->mesh_obj,
|
|
||||||
&((*bat_attr)->attr));
|
|
||||||
if (err) {
|
|
||||||
bat_err(dev, "Can't add sysfs file: %s/%s/%s\n",
|
|
||||||
dev->name, SYSFS_IF_MESH_SUBDIR,
|
|
||||||
((*bat_attr)->attr).name);
|
|
||||||
goto rem_attr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
rem_attr:
|
|
||||||
for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr)
|
|
||||||
sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr));
|
|
||||||
|
|
||||||
kobject_put(bat_priv->mesh_obj);
|
|
||||||
bat_priv->mesh_obj = NULL;
|
|
||||||
out:
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sysfs_del_meshif(struct net_device *dev)
|
|
||||||
{
|
|
||||||
struct bat_priv *bat_priv = netdev_priv(dev);
|
|
||||||
struct bat_attribute **bat_attr;
|
|
||||||
|
|
||||||
for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr)
|
|
||||||
sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr));
|
|
||||||
|
|
||||||
kobject_put(bat_priv->mesh_obj);
|
|
||||||
bat_priv->mesh_obj = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t show_mesh_iface(struct kobject *kobj, struct attribute *attr,
|
|
||||||
char *buff)
|
|
||||||
{
|
|
||||||
struct device *dev = to_dev(kobj->parent);
|
|
||||||
struct net_device *net_dev = to_net_dev(dev);
|
|
||||||
struct batman_if *batman_if = get_batman_if_by_netdev(net_dev);
|
|
||||||
ssize_t length;
|
|
||||||
|
|
||||||
if (!batman_if)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
length = sprintf(buff, "%s\n", batman_if->if_status == IF_NOT_IN_USE ?
|
|
||||||
"none" : batman_if->soft_iface->name);
|
|
||||||
|
|
||||||
hardif_put(batman_if);
|
|
||||||
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t store_mesh_iface(struct kobject *kobj, struct attribute *attr,
|
|
||||||
char *buff, size_t count)
|
|
||||||
{
|
|
||||||
struct device *dev = to_dev(kobj->parent);
|
|
||||||
struct net_device *net_dev = to_net_dev(dev);
|
|
||||||
struct batman_if *batman_if = get_batman_if_by_netdev(net_dev);
|
|
||||||
int status_tmp = -1;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (!batman_if)
|
|
||||||
return count;
|
|
||||||
|
|
||||||
if (buff[count - 1] == '\n')
|
|
||||||
buff[count - 1] = '\0';
|
|
||||||
|
|
||||||
if (strlen(buff) >= IFNAMSIZ) {
|
|
||||||
pr_err("Invalid parameter for 'mesh_iface' setting received: "
|
|
||||||
"interface name too long '%s'\n", buff);
|
|
||||||
hardif_put(batman_if);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strncmp(buff, "none", 4) == 0)
|
|
||||||
status_tmp = IF_NOT_IN_USE;
|
|
||||||
else
|
|
||||||
status_tmp = IF_I_WANT_YOU;
|
|
||||||
|
|
||||||
if ((batman_if->if_status == status_tmp) || ((batman_if->soft_iface) &&
|
|
||||||
(strncmp(batman_if->soft_iface->name, buff, IFNAMSIZ) == 0))) {
|
|
||||||
hardif_put(batman_if);
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status_tmp == IF_NOT_IN_USE) {
|
|
||||||
rtnl_lock();
|
|
||||||
hardif_disable_interface(batman_if);
|
|
||||||
rtnl_unlock();
|
|
||||||
hardif_put(batman_if);
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if the interface already is in use */
|
|
||||||
if (batman_if->if_status != IF_NOT_IN_USE) {
|
|
||||||
rtnl_lock();
|
|
||||||
hardif_disable_interface(batman_if);
|
|
||||||
rtnl_unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = hardif_enable_interface(batman_if, buff);
|
|
||||||
hardif_put(batman_if);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t show_iface_status(struct kobject *kobj, struct attribute *attr,
|
|
||||||
char *buff)
|
|
||||||
{
|
|
||||||
struct device *dev = to_dev(kobj->parent);
|
|
||||||
struct net_device *net_dev = to_net_dev(dev);
|
|
||||||
struct batman_if *batman_if = get_batman_if_by_netdev(net_dev);
|
|
||||||
ssize_t length;
|
|
||||||
|
|
||||||
if (!batman_if)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
switch (batman_if->if_status) {
|
|
||||||
case IF_TO_BE_REMOVED:
|
|
||||||
length = sprintf(buff, "disabling\n");
|
|
||||||
break;
|
|
||||||
case IF_INACTIVE:
|
|
||||||
length = sprintf(buff, "inactive\n");
|
|
||||||
break;
|
|
||||||
case IF_ACTIVE:
|
|
||||||
length = sprintf(buff, "active\n");
|
|
||||||
break;
|
|
||||||
case IF_TO_BE_ACTIVATED:
|
|
||||||
length = sprintf(buff, "enabling\n");
|
|
||||||
break;
|
|
||||||
case IF_NOT_IN_USE:
|
|
||||||
default:
|
|
||||||
length = sprintf(buff, "not in use\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
hardif_put(batman_if);
|
|
||||||
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BAT_ATTR(mesh_iface, S_IRUGO | S_IWUSR,
|
|
||||||
show_mesh_iface, store_mesh_iface);
|
|
||||||
static BAT_ATTR(iface_status, S_IRUGO, show_iface_status, NULL);
|
|
||||||
|
|
||||||
static struct bat_attribute *batman_attrs[] = {
|
|
||||||
&bat_attr_mesh_iface,
|
|
||||||
&bat_attr_iface_status,
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
int sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev)
|
|
||||||
{
|
|
||||||
struct kobject *hardif_kobject = &dev->dev.kobj;
|
|
||||||
struct bat_attribute **bat_attr;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
*hardif_obj = kobject_create_and_add(SYSFS_IF_BAT_SUBDIR,
|
|
||||||
hardif_kobject);
|
|
||||||
|
|
||||||
if (!*hardif_obj) {
|
|
||||||
bat_err(dev, "Can't add sysfs directory: %s/%s\n", dev->name,
|
|
||||||
SYSFS_IF_BAT_SUBDIR);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (bat_attr = batman_attrs; *bat_attr; ++bat_attr) {
|
|
||||||
err = sysfs_create_file(*hardif_obj, &((*bat_attr)->attr));
|
|
||||||
if (err) {
|
|
||||||
bat_err(dev, "Can't add sysfs file: %s/%s/%s\n",
|
|
||||||
dev->name, SYSFS_IF_BAT_SUBDIR,
|
|
||||||
((*bat_attr)->attr).name);
|
|
||||||
goto rem_attr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
rem_attr:
|
|
||||||
for (bat_attr = batman_attrs; *bat_attr; ++bat_attr)
|
|
||||||
sysfs_remove_file(*hardif_obj, &((*bat_attr)->attr));
|
|
||||||
out:
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sysfs_del_hardif(struct kobject **hardif_obj)
|
|
||||||
{
|
|
||||||
kobject_put(*hardif_obj);
|
|
||||||
*hardif_obj = NULL;
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2010 B.A.T.M.A.N. contributors:
|
|
||||||
*
|
|
||||||
* Marek Lindner
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of version 2 of the GNU General Public
|
|
||||||
* License as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
||||||
* 02110-1301, USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _NET_BATMAN_ADV_SYSFS_H_
|
|
||||||
#define _NET_BATMAN_ADV_SYSFS_H_
|
|
||||||
|
|
||||||
#define SYSFS_IF_MESH_SUBDIR "mesh"
|
|
||||||
#define SYSFS_IF_BAT_SUBDIR "batman_adv"
|
|
||||||
|
|
||||||
struct bat_attribute {
|
|
||||||
struct attribute attr;
|
|
||||||
ssize_t (*show)(struct kobject *kobj, struct attribute *attr,
|
|
||||||
char *buf);
|
|
||||||
ssize_t (*store)(struct kobject *kobj, struct attribute *attr,
|
|
||||||
char *buf, size_t count);
|
|
||||||
};
|
|
||||||
|
|
||||||
int sysfs_add_meshif(struct net_device *dev);
|
|
||||||
void sysfs_del_meshif(struct net_device *dev);
|
|
||||||
int sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev);
|
|
||||||
void sysfs_del_hardif(struct kobject **hardif_obj);
|
|
||||||
|
|
||||||
#endif /* _NET_BATMAN_ADV_SYSFS_H_ */
|
|
@ -1,201 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2006-2010 B.A.T.M.A.N. contributors:
|
|
||||||
*
|
|
||||||
* Simon Wunderlich, Marek Lindner
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of version 2 of the GNU General Public
|
|
||||||
* License as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
||||||
* 02110-1301, USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "main.h"
|
|
||||||
#include "bitarray.h"
|
|
||||||
|
|
||||||
#include <linux/bitops.h>
|
|
||||||
|
|
||||||
/* returns true if the corresponding bit in the given seq_bits indicates true
|
|
||||||
* and curr_seqno is within range of last_seqno */
|
|
||||||
uint8_t get_bit_status(TYPE_OF_WORD *seq_bits, uint32_t last_seqno,
|
|
||||||
uint32_t curr_seqno)
|
|
||||||
{
|
|
||||||
int32_t diff, word_offset, word_num;
|
|
||||||
|
|
||||||
diff = last_seqno - curr_seqno;
|
|
||||||
if (diff < 0 || diff >= TQ_LOCAL_WINDOW_SIZE) {
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
/* which word */
|
|
||||||
word_num = (last_seqno - curr_seqno) / WORD_BIT_SIZE;
|
|
||||||
/* which position in the selected word */
|
|
||||||
word_offset = (last_seqno - curr_seqno) % WORD_BIT_SIZE;
|
|
||||||
|
|
||||||
if (seq_bits[word_num] & 1 << word_offset)
|
|
||||||
return 1;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* turn corresponding bit on, so we can remember that we got the packet */
|
|
||||||
void bit_mark(TYPE_OF_WORD *seq_bits, int32_t n)
|
|
||||||
{
|
|
||||||
int32_t word_offset, word_num;
|
|
||||||
|
|
||||||
/* if too old, just drop it */
|
|
||||||
if (n < 0 || n >= TQ_LOCAL_WINDOW_SIZE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* which word */
|
|
||||||
word_num = n / WORD_BIT_SIZE;
|
|
||||||
/* which position in the selected word */
|
|
||||||
word_offset = n % WORD_BIT_SIZE;
|
|
||||||
|
|
||||||
seq_bits[word_num] |= 1 << word_offset; /* turn the position on */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* shift the packet array by n places. */
|
|
||||||
static void bit_shift(TYPE_OF_WORD *seq_bits, int32_t n)
|
|
||||||
{
|
|
||||||
int32_t word_offset, word_num;
|
|
||||||
int32_t i;
|
|
||||||
|
|
||||||
if (n <= 0 || n >= TQ_LOCAL_WINDOW_SIZE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
word_offset = n % WORD_BIT_SIZE;/* shift how much inside each word */
|
|
||||||
word_num = n / WORD_BIT_SIZE; /* shift over how much (full) words */
|
|
||||||
|
|
||||||
for (i = NUM_WORDS - 1; i > word_num; i--) {
|
|
||||||
/* going from old to new, so we don't overwrite the data we copy
|
|
||||||
* from.
|
|
||||||
*
|
|
||||||
* left is high, right is low: FEDC BA98 7654 3210
|
|
||||||
* ^^ ^^
|
|
||||||
* vvvv
|
|
||||||
* ^^^^ = from, vvvvv =to, we'd have word_num==1 and
|
|
||||||
* word_offset==WORD_BIT_SIZE/2 ????? in this example.
|
|
||||||
* (=24 bits)
|
|
||||||
*
|
|
||||||
* our desired output would be: 9876 5432 1000 0000
|
|
||||||
* */
|
|
||||||
|
|
||||||
seq_bits[i] =
|
|
||||||
(seq_bits[i - word_num] << word_offset) +
|
|
||||||
/* take the lower port from the left half, shift it left
|
|
||||||
* to its final position */
|
|
||||||
(seq_bits[i - word_num - 1] >>
|
|
||||||
(WORD_BIT_SIZE-word_offset));
|
|
||||||
/* and the upper part of the right half and shift it left to
|
|
||||||
* it's position */
|
|
||||||
/* for our example that would be: word[0] = 9800 + 0076 =
|
|
||||||
* 9876 */
|
|
||||||
}
|
|
||||||
/* now for our last word, i==word_num, we only have the it's "left"
|
|
||||||
* half. that's the 1000 word in our example.*/
|
|
||||||
|
|
||||||
seq_bits[i] = (seq_bits[i - word_num] << word_offset);
|
|
||||||
|
|
||||||
/* pad the rest with 0, if there is anything */
|
|
||||||
i--;
|
|
||||||
|
|
||||||
for (; i >= 0; i--)
|
|
||||||
seq_bits[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void bit_reset_window(TYPE_OF_WORD *seq_bits)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < NUM_WORDS; i++)
|
|
||||||
seq_bits[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* receive and process one packet within the sequence number window.
|
|
||||||
*
|
|
||||||
* returns:
|
|
||||||
* 1 if the window was moved (either new or very old)
|
|
||||||
* 0 if the window was not moved/shifted.
|
|
||||||
*/
|
|
||||||
char bit_get_packet(void *priv, TYPE_OF_WORD *seq_bits,
|
|
||||||
int32_t seq_num_diff, int8_t set_mark)
|
|
||||||
{
|
|
||||||
struct bat_priv *bat_priv = (struct bat_priv *)priv;
|
|
||||||
|
|
||||||
/* sequence number is slightly older. We already got a sequence number
|
|
||||||
* higher than this one, so we just mark it. */
|
|
||||||
|
|
||||||
if ((seq_num_diff <= 0) && (seq_num_diff > -TQ_LOCAL_WINDOW_SIZE)) {
|
|
||||||
if (set_mark)
|
|
||||||
bit_mark(seq_bits, -seq_num_diff);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* sequence number is slightly newer, so we shift the window and
|
|
||||||
* set the mark if required */
|
|
||||||
|
|
||||||
if ((seq_num_diff > 0) && (seq_num_diff < TQ_LOCAL_WINDOW_SIZE)) {
|
|
||||||
bit_shift(seq_bits, seq_num_diff);
|
|
||||||
|
|
||||||
if (set_mark)
|
|
||||||
bit_mark(seq_bits, 0);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* sequence number is much newer, probably missed a lot of packets */
|
|
||||||
|
|
||||||
if ((seq_num_diff >= TQ_LOCAL_WINDOW_SIZE)
|
|
||||||
|| (seq_num_diff < EXPECTED_SEQNO_RANGE)) {
|
|
||||||
bat_dbg(DBG_BATMAN, bat_priv,
|
|
||||||
"We missed a lot of packets (%i) !\n",
|
|
||||||
seq_num_diff - 1);
|
|
||||||
bit_reset_window(seq_bits);
|
|
||||||
if (set_mark)
|
|
||||||
bit_mark(seq_bits, 0);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* received a much older packet. The other host either restarted
|
|
||||||
* or the old packet got delayed somewhere in the network. The
|
|
||||||
* packet should be dropped without calling this function if the
|
|
||||||
* seqno window is protected. */
|
|
||||||
|
|
||||||
if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE)
|
|
||||||
|| (seq_num_diff >= EXPECTED_SEQNO_RANGE)) {
|
|
||||||
|
|
||||||
bat_dbg(DBG_BATMAN, bat_priv,
|
|
||||||
"Other host probably restarted!\n");
|
|
||||||
|
|
||||||
bit_reset_window(seq_bits);
|
|
||||||
if (set_mark)
|
|
||||||
bit_mark(seq_bits, 0);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* never reached */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* count the hamming weight, how many good packets did we receive? just count
|
|
||||||
* the 1's.
|
|
||||||
*/
|
|
||||||
int bit_packet_count(TYPE_OF_WORD *seq_bits)
|
|
||||||
{
|
|
||||||
int i, hamming = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < NUM_WORDS; i++)
|
|
||||||
hamming += hweight_long(seq_bits[i]);
|
|
||||||
|
|
||||||
return hamming;
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2006-2010 B.A.T.M.A.N. contributors:
|
|
||||||
*
|
|
||||||
* Simon Wunderlich, Marek Lindner
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of version 2 of the GNU General Public
|
|
||||||
* License as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
||||||
* 02110-1301, USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _NET_BATMAN_ADV_BITARRAY_H_
|
|
||||||
#define _NET_BATMAN_ADV_BITARRAY_H_
|
|
||||||
|
|
||||||
/* you should choose something big, if you don't want to waste cpu
|
|
||||||
* and keep the type in sync with bit_packet_count */
|
|
||||||
#define TYPE_OF_WORD unsigned long
|
|
||||||
#define WORD_BIT_SIZE (sizeof(TYPE_OF_WORD) * 8)
|
|
||||||
|
|
||||||
/* returns true if the corresponding bit in the given seq_bits indicates true
|
|
||||||
* and curr_seqno is within range of last_seqno */
|
|
||||||
uint8_t get_bit_status(TYPE_OF_WORD *seq_bits, uint32_t last_seqno,
|
|
||||||
uint32_t curr_seqno);
|
|
||||||
|
|
||||||
/* turn corresponding bit on, so we can remember that we got the packet */
|
|
||||||
void bit_mark(TYPE_OF_WORD *seq_bits, int32_t n);
|
|
||||||
|
|
||||||
|
|
||||||
/* receive and process one packet, returns 1 if received seq_num is considered
|
|
||||||
* new, 0 if old */
|
|
||||||
char bit_get_packet(void *priv, TYPE_OF_WORD *seq_bits,
|
|
||||||
int32_t seq_num_diff, int8_t set_mark);
|
|
||||||
|
|
||||||
/* count the hamming weight, how many good packets did we receive? */
|
|
||||||
int bit_packet_count(TYPE_OF_WORD *seq_bits);
|
|
||||||
|
|
||||||
#endif /* _NET_BATMAN_ADV_BITARRAY_H_ */
|
|
@ -1,647 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
|
|
||||||
*
|
|
||||||
* Marek Lindner, Simon Wunderlich
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of version 2 of the GNU General Public
|
|
||||||
* License as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
||||||
* 02110-1301, USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "main.h"
|
|
||||||
#include "hard-interface.h"
|
|
||||||
#include "soft-interface.h"
|
|
||||||
#include "send.h"
|
|
||||||
#include "translation-table.h"
|
|
||||||
#include "routing.h"
|
|
||||||
#include "bat_sysfs.h"
|
|
||||||
#include "originator.h"
|
|
||||||
#include "hash.h"
|
|
||||||
|
|
||||||
#include <linux/if_arp.h>
|
|
||||||
|
|
||||||
#define MIN(x, y) ((x) < (y) ? (x) : (y))
|
|
||||||
|
|
||||||
/* protect update critical side of if_list - but not the content */
|
|
||||||
static DEFINE_SPINLOCK(if_list_lock);
|
|
||||||
|
|
||||||
struct batman_if *get_batman_if_by_netdev(struct net_device *net_dev)
|
|
||||||
{
|
|
||||||
struct batman_if *batman_if;
|
|
||||||
|
|
||||||
rcu_read_lock();
|
|
||||||
list_for_each_entry_rcu(batman_if, &if_list, list) {
|
|
||||||
if (batman_if->net_dev == net_dev)
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
batman_if = NULL;
|
|
||||||
|
|
||||||
out:
|
|
||||||
if (batman_if)
|
|
||||||
hardif_hold(batman_if);
|
|
||||||
|
|
||||||
rcu_read_unlock();
|
|
||||||
return batman_if;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int is_valid_iface(struct net_device *net_dev)
|
|
||||||
{
|
|
||||||
if (net_dev->flags & IFF_LOOPBACK)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (net_dev->type != ARPHRD_ETHER)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (net_dev->addr_len != ETH_ALEN)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* no batman over batman */
|
|
||||||
#ifdef HAVE_NET_DEVICE_OPS
|
|
||||||
if (net_dev->netdev_ops->ndo_start_xmit == interface_tx)
|
|
||||||
return 0;
|
|
||||||
#else
|
|
||||||
if (net_dev->hard_start_xmit == interface_tx)
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Device is being bridged */
|
|
||||||
/* if (net_dev->priv_flags & IFF_BRIDGE_PORT)
|
|
||||||
return 0; */
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct batman_if *get_active_batman_if(struct net_device *soft_iface)
|
|
||||||
{
|
|
||||||
struct batman_if *batman_if;
|
|
||||||
|
|
||||||
rcu_read_lock();
|
|
||||||
list_for_each_entry_rcu(batman_if, &if_list, list) {
|
|
||||||
if (batman_if->soft_iface != soft_iface)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (batman_if->if_status == IF_ACTIVE)
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
batman_if = NULL;
|
|
||||||
|
|
||||||
out:
|
|
||||||
if (batman_if)
|
|
||||||
hardif_hold(batman_if);
|
|
||||||
|
|
||||||
rcu_read_unlock();
|
|
||||||
return batman_if;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void update_primary_addr(struct bat_priv *bat_priv)
|
|
||||||
{
|
|
||||||
struct vis_packet *vis_packet;
|
|
||||||
|
|
||||||
vis_packet = (struct vis_packet *)
|
|
||||||
bat_priv->my_vis_info->skb_packet->data;
|
|
||||||
memcpy(vis_packet->vis_orig,
|
|
||||||
bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
|
|
||||||
memcpy(vis_packet->sender_orig,
|
|
||||||
bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void set_primary_if(struct bat_priv *bat_priv,
|
|
||||||
struct batman_if *batman_if)
|
|
||||||
{
|
|
||||||
struct batman_packet *batman_packet;
|
|
||||||
struct batman_if *old_if;
|
|
||||||
|
|
||||||
if (batman_if)
|
|
||||||
hardif_hold(batman_if);
|
|
||||||
|
|
||||||
old_if = bat_priv->primary_if;
|
|
||||||
bat_priv->primary_if = batman_if;
|
|
||||||
|
|
||||||
if (old_if)
|
|
||||||
hardif_put(old_if);
|
|
||||||
|
|
||||||
if (!bat_priv->primary_if)
|
|
||||||
return;
|
|
||||||
|
|
||||||
batman_packet = (struct batman_packet *)(batman_if->packet_buff);
|
|
||||||
batman_packet->flags = PRIMARIES_FIRST_HOP;
|
|
||||||
batman_packet->ttl = TTL;
|
|
||||||
|
|
||||||
update_primary_addr(bat_priv);
|
|
||||||
|
|
||||||
/***
|
|
||||||
* hacky trick to make sure that we send the HNA information via
|
|
||||||
* our new primary interface
|
|
||||||
*/
|
|
||||||
atomic_set(&bat_priv->hna_local_changed, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool hardif_is_iface_up(struct batman_if *batman_if)
|
|
||||||
{
|
|
||||||
if (batman_if->net_dev->flags & IFF_UP)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void update_mac_addresses(struct batman_if *batman_if)
|
|
||||||
{
|
|
||||||
memcpy(((struct batman_packet *)(batman_if->packet_buff))->orig,
|
|
||||||
batman_if->net_dev->dev_addr, ETH_ALEN);
|
|
||||||
memcpy(((struct batman_packet *)(batman_if->packet_buff))->prev_sender,
|
|
||||||
batman_if->net_dev->dev_addr, ETH_ALEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void check_known_mac_addr(struct net_device *net_dev)
|
|
||||||
{
|
|
||||||
struct batman_if *batman_if;
|
|
||||||
|
|
||||||
rcu_read_lock();
|
|
||||||
list_for_each_entry_rcu(batman_if, &if_list, list) {
|
|
||||||
if ((batman_if->if_status != IF_ACTIVE) &&
|
|
||||||
(batman_if->if_status != IF_TO_BE_ACTIVATED))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (batman_if->net_dev == net_dev)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!compare_orig(batman_if->net_dev->dev_addr,
|
|
||||||
net_dev->dev_addr))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
pr_warning("The newly added mac address (%pM) already exists "
|
|
||||||
"on: %s\n", net_dev->dev_addr,
|
|
||||||
batman_if->net_dev->name);
|
|
||||||
pr_warning("It is strongly recommended to keep mac addresses "
|
|
||||||
"unique to avoid problems!\n");
|
|
||||||
}
|
|
||||||
rcu_read_unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
int hardif_min_mtu(struct net_device *soft_iface)
|
|
||||||
{
|
|
||||||
struct bat_priv *bat_priv = netdev_priv(soft_iface);
|
|
||||||
struct batman_if *batman_if;
|
|
||||||
/* allow big frames if all devices are capable to do so
|
|
||||||
* (have MTU > 1500 + BAT_HEADER_LEN) */
|
|
||||||
int min_mtu = ETH_DATA_LEN;
|
|
||||||
|
|
||||||
if (atomic_read(&bat_priv->frag_enabled))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
rcu_read_lock();
|
|
||||||
list_for_each_entry_rcu(batman_if, &if_list, list) {
|
|
||||||
if ((batman_if->if_status != IF_ACTIVE) &&
|
|
||||||
(batman_if->if_status != IF_TO_BE_ACTIVATED))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (batman_if->soft_iface != soft_iface)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
min_mtu = MIN(batman_if->net_dev->mtu - BAT_HEADER_LEN,
|
|
||||||
min_mtu);
|
|
||||||
}
|
|
||||||
rcu_read_unlock();
|
|
||||||
out:
|
|
||||||
return min_mtu;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* adjusts the MTU if a new interface with a smaller MTU appeared. */
|
|
||||||
void update_min_mtu(struct net_device *soft_iface)
|
|
||||||
{
|
|
||||||
int min_mtu;
|
|
||||||
|
|
||||||
min_mtu = hardif_min_mtu(soft_iface);
|
|
||||||
if (soft_iface->mtu != min_mtu)
|
|
||||||
soft_iface->mtu = min_mtu;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void hardif_activate_interface(struct batman_if *batman_if)
|
|
||||||
{
|
|
||||||
struct bat_priv *bat_priv;
|
|
||||||
|
|
||||||
if (batman_if->if_status != IF_INACTIVE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
bat_priv = netdev_priv(batman_if->soft_iface);
|
|
||||||
|
|
||||||
update_mac_addresses(batman_if);
|
|
||||||
batman_if->if_status = IF_TO_BE_ACTIVATED;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* the first active interface becomes our primary interface or
|
|
||||||
* the next active interface after the old primay interface was removed
|
|
||||||
*/
|
|
||||||
if (!bat_priv->primary_if)
|
|
||||||
set_primary_if(bat_priv, batman_if);
|
|
||||||
|
|
||||||
bat_info(batman_if->soft_iface, "Interface activated: %s\n",
|
|
||||||
batman_if->net_dev->name);
|
|
||||||
|
|
||||||
update_min_mtu(batman_if->soft_iface);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void hardif_deactivate_interface(struct batman_if *batman_if)
|
|
||||||
{
|
|
||||||
if ((batman_if->if_status != IF_ACTIVE) &&
|
|
||||||
(batman_if->if_status != IF_TO_BE_ACTIVATED))
|
|
||||||
return;
|
|
||||||
|
|
||||||
batman_if->if_status = IF_INACTIVE;
|
|
||||||
|
|
||||||
bat_info(batman_if->soft_iface, "Interface deactivated: %s\n",
|
|
||||||
batman_if->net_dev->name);
|
|
||||||
|
|
||||||
update_min_mtu(batman_if->soft_iface);
|
|
||||||
}
|
|
||||||
|
|
||||||
int hardif_enable_interface(struct batman_if *batman_if, char *iface_name)
|
|
||||||
{
|
|
||||||
struct bat_priv *bat_priv;
|
|
||||||
struct batman_packet *batman_packet;
|
|
||||||
|
|
||||||
if (batman_if->if_status != IF_NOT_IN_USE)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
batman_if->soft_iface = dev_get_by_name(&init_net, iface_name);
|
|
||||||
|
|
||||||
if (!batman_if->soft_iface) {
|
|
||||||
batman_if->soft_iface = softif_create(iface_name);
|
|
||||||
|
|
||||||
if (!batman_if->soft_iface)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
/* dev_get_by_name() increases the reference counter for us */
|
|
||||||
dev_hold(batman_if->soft_iface);
|
|
||||||
}
|
|
||||||
|
|
||||||
bat_priv = netdev_priv(batman_if->soft_iface);
|
|
||||||
batman_if->packet_len = BAT_PACKET_LEN;
|
|
||||||
batman_if->packet_buff = kmalloc(batman_if->packet_len, GFP_ATOMIC);
|
|
||||||
|
|
||||||
if (!batman_if->packet_buff) {
|
|
||||||
bat_err(batman_if->soft_iface, "Can't add interface packet "
|
|
||||||
"(%s): out of memory\n", batman_if->net_dev->name);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
batman_packet = (struct batman_packet *)(batman_if->packet_buff);
|
|
||||||
batman_packet->packet_type = BAT_PACKET;
|
|
||||||
batman_packet->version = COMPAT_VERSION;
|
|
||||||
batman_packet->flags = 0;
|
|
||||||
batman_packet->ttl = 2;
|
|
||||||
batman_packet->tq = TQ_MAX_VALUE;
|
|
||||||
batman_packet->num_hna = 0;
|
|
||||||
|
|
||||||
batman_if->if_num = bat_priv->num_ifaces;
|
|
||||||
bat_priv->num_ifaces++;
|
|
||||||
batman_if->if_status = IF_INACTIVE;
|
|
||||||
orig_hash_add_if(batman_if, bat_priv->num_ifaces);
|
|
||||||
|
|
||||||
batman_if->batman_adv_ptype.type = __constant_htons(ETH_P_BATMAN);
|
|
||||||
batman_if->batman_adv_ptype.func = batman_skb_recv;
|
|
||||||
batman_if->batman_adv_ptype.dev = batman_if->net_dev;
|
|
||||||
hardif_hold(batman_if);
|
|
||||||
dev_add_pack(&batman_if->batman_adv_ptype);
|
|
||||||
|
|
||||||
atomic_set(&batman_if->seqno, 1);
|
|
||||||
atomic_set(&batman_if->frag_seqno, 1);
|
|
||||||
bat_info(batman_if->soft_iface, "Adding interface: %s\n",
|
|
||||||
batman_if->net_dev->name);
|
|
||||||
|
|
||||||
if (atomic_read(&bat_priv->frag_enabled) && batman_if->net_dev->mtu <
|
|
||||||
ETH_DATA_LEN + BAT_HEADER_LEN)
|
|
||||||
bat_info(batman_if->soft_iface,
|
|
||||||
"The MTU of interface %s is too small (%i) to handle "
|
|
||||||
"the transport of batman-adv packets. Packets going "
|
|
||||||
"over this interface will be fragmented on layer2 "
|
|
||||||
"which could impact the performance. Setting the MTU "
|
|
||||||
"to %zi would solve the problem.\n",
|
|
||||||
batman_if->net_dev->name, batman_if->net_dev->mtu,
|
|
||||||
ETH_DATA_LEN + BAT_HEADER_LEN);
|
|
||||||
|
|
||||||
if (!atomic_read(&bat_priv->frag_enabled) && batman_if->net_dev->mtu <
|
|
||||||
ETH_DATA_LEN + BAT_HEADER_LEN)
|
|
||||||
bat_info(batman_if->soft_iface,
|
|
||||||
"The MTU of interface %s is too small (%i) to handle "
|
|
||||||
"the transport of batman-adv packets. If you experience"
|
|
||||||
" problems getting traffic through try increasing the "
|
|
||||||
"MTU to %zi.\n",
|
|
||||||
batman_if->net_dev->name, batman_if->net_dev->mtu,
|
|
||||||
ETH_DATA_LEN + BAT_HEADER_LEN);
|
|
||||||
|
|
||||||
if (hardif_is_iface_up(batman_if))
|
|
||||||
hardif_activate_interface(batman_if);
|
|
||||||
else
|
|
||||||
bat_err(batman_if->soft_iface, "Not using interface %s "
|
|
||||||
"(retrying later): interface not active\n",
|
|
||||||
batman_if->net_dev->name);
|
|
||||||
|
|
||||||
/* begin scheduling originator messages on that interface */
|
|
||||||
schedule_own_packet(batman_if);
|
|
||||||
|
|
||||||
out:
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
err:
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
void hardif_disable_interface(struct batman_if *batman_if)
|
|
||||||
{
|
|
||||||
struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface);
|
|
||||||
|
|
||||||
if (batman_if->if_status == IF_ACTIVE)
|
|
||||||
hardif_deactivate_interface(batman_if);
|
|
||||||
|
|
||||||
if (batman_if->if_status != IF_INACTIVE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
bat_info(batman_if->soft_iface, "Removing interface: %s\n",
|
|
||||||
batman_if->net_dev->name);
|
|
||||||
dev_remove_pack(&batman_if->batman_adv_ptype);
|
|
||||||
hardif_put(batman_if);
|
|
||||||
|
|
||||||
bat_priv->num_ifaces--;
|
|
||||||
orig_hash_del_if(batman_if, bat_priv->num_ifaces);
|
|
||||||
|
|
||||||
if (batman_if == bat_priv->primary_if) {
|
|
||||||
struct batman_if *new_if;
|
|
||||||
|
|
||||||
new_if = get_active_batman_if(batman_if->soft_iface);
|
|
||||||
set_primary_if(bat_priv, new_if);
|
|
||||||
|
|
||||||
if (new_if)
|
|
||||||
hardif_put(new_if);
|
|
||||||
}
|
|
||||||
|
|
||||||
kfree(batman_if->packet_buff);
|
|
||||||
batman_if->packet_buff = NULL;
|
|
||||||
batman_if->if_status = IF_NOT_IN_USE;
|
|
||||||
|
|
||||||
/* delete all references to this batman_if */
|
|
||||||
purge_orig_ref(bat_priv);
|
|
||||||
purge_outstanding_packets(bat_priv, batman_if);
|
|
||||||
dev_put(batman_if->soft_iface);
|
|
||||||
|
|
||||||
/* nobody uses this interface anymore */
|
|
||||||
if (!bat_priv->num_ifaces)
|
|
||||||
softif_destroy(batman_if->soft_iface);
|
|
||||||
|
|
||||||
batman_if->soft_iface = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct batman_if *hardif_add_interface(struct net_device *net_dev)
|
|
||||||
{
|
|
||||||
struct batman_if *batman_if;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = is_valid_iface(net_dev);
|
|
||||||
if (ret != 1)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
dev_hold(net_dev);
|
|
||||||
|
|
||||||
batman_if = kmalloc(sizeof(struct batman_if), GFP_ATOMIC);
|
|
||||||
if (!batman_if) {
|
|
||||||
pr_err("Can't add interface (%s): out of memory\n",
|
|
||||||
net_dev->name);
|
|
||||||
goto release_dev;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = sysfs_add_hardif(&batman_if->hardif_obj, net_dev);
|
|
||||||
if (ret)
|
|
||||||
goto free_if;
|
|
||||||
|
|
||||||
batman_if->if_num = -1;
|
|
||||||
batman_if->net_dev = net_dev;
|
|
||||||
batman_if->soft_iface = NULL;
|
|
||||||
batman_if->if_status = IF_NOT_IN_USE;
|
|
||||||
INIT_LIST_HEAD(&batman_if->list);
|
|
||||||
atomic_set(&batman_if->refcnt, 0);
|
|
||||||
hardif_hold(batman_if);
|
|
||||||
|
|
||||||
check_known_mac_addr(batman_if->net_dev);
|
|
||||||
|
|
||||||
spin_lock(&if_list_lock);
|
|
||||||
list_add_tail_rcu(&batman_if->list, &if_list);
|
|
||||||
spin_unlock(&if_list_lock);
|
|
||||||
|
|
||||||
/* extra reference for return */
|
|
||||||
hardif_hold(batman_if);
|
|
||||||
return batman_if;
|
|
||||||
|
|
||||||
free_if:
|
|
||||||
kfree(batman_if);
|
|
||||||
release_dev:
|
|
||||||
dev_put(net_dev);
|
|
||||||
out:
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void hardif_remove_interface(struct batman_if *batman_if)
|
|
||||||
{
|
|
||||||
/* first deactivate interface */
|
|
||||||
if (batman_if->if_status != IF_NOT_IN_USE)
|
|
||||||
hardif_disable_interface(batman_if);
|
|
||||||
|
|
||||||
if (batman_if->if_status != IF_NOT_IN_USE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
batman_if->if_status = IF_TO_BE_REMOVED;
|
|
||||||
synchronize_rcu();
|
|
||||||
sysfs_del_hardif(&batman_if->hardif_obj);
|
|
||||||
hardif_put(batman_if);
|
|
||||||
}
|
|
||||||
|
|
||||||
void hardif_remove_interfaces(void)
|
|
||||||
{
|
|
||||||
struct batman_if *batman_if, *batman_if_tmp;
|
|
||||||
struct list_head if_queue;
|
|
||||||
|
|
||||||
INIT_LIST_HEAD(&if_queue);
|
|
||||||
|
|
||||||
spin_lock(&if_list_lock);
|
|
||||||
list_for_each_entry_safe(batman_if, batman_if_tmp, &if_list, list) {
|
|
||||||
list_del_rcu(&batman_if->list);
|
|
||||||
list_add_tail(&batman_if->list, &if_queue);
|
|
||||||
}
|
|
||||||
spin_unlock(&if_list_lock);
|
|
||||||
|
|
||||||
rtnl_lock();
|
|
||||||
list_for_each_entry_safe(batman_if, batman_if_tmp, &if_queue, list) {
|
|
||||||
hardif_remove_interface(batman_if);
|
|
||||||
}
|
|
||||||
rtnl_unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
static int hard_if_event(struct notifier_block *this,
|
|
||||||
unsigned long event, void *ptr)
|
|
||||||
{
|
|
||||||
struct net_device *net_dev = (struct net_device *)ptr;
|
|
||||||
struct batman_if *batman_if = get_batman_if_by_netdev(net_dev);
|
|
||||||
struct bat_priv *bat_priv;
|
|
||||||
|
|
||||||
if (!batman_if && event == NETDEV_REGISTER)
|
|
||||||
batman_if = hardif_add_interface(net_dev);
|
|
||||||
|
|
||||||
if (!batman_if)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
switch (event) {
|
|
||||||
case NETDEV_UP:
|
|
||||||
hardif_activate_interface(batman_if);
|
|
||||||
break;
|
|
||||||
case NETDEV_GOING_DOWN:
|
|
||||||
case NETDEV_DOWN:
|
|
||||||
hardif_deactivate_interface(batman_if);
|
|
||||||
break;
|
|
||||||
case NETDEV_UNREGISTER:
|
|
||||||
spin_lock(&if_list_lock);
|
|
||||||
list_del_rcu(&batman_if->list);
|
|
||||||
spin_unlock(&if_list_lock);
|
|
||||||
|
|
||||||
hardif_remove_interface(batman_if);
|
|
||||||
break;
|
|
||||||
case NETDEV_CHANGEMTU:
|
|
||||||
if (batman_if->soft_iface)
|
|
||||||
update_min_mtu(batman_if->soft_iface);
|
|
||||||
break;
|
|
||||||
case NETDEV_CHANGEADDR:
|
|
||||||
if (batman_if->if_status == IF_NOT_IN_USE) {
|
|
||||||
hardif_put(batman_if);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
check_known_mac_addr(batman_if->net_dev);
|
|
||||||
update_mac_addresses(batman_if);
|
|
||||||
|
|
||||||
bat_priv = netdev_priv(batman_if->soft_iface);
|
|
||||||
if (batman_if == bat_priv->primary_if)
|
|
||||||
update_primary_addr(bat_priv);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
hardif_put(batman_if);
|
|
||||||
|
|
||||||
out:
|
|
||||||
return NOTIFY_DONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* receive a packet with the batman ethertype coming on a hard
|
|
||||||
* interface */
|
|
||||||
int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
|
|
||||||
struct packet_type *ptype, struct net_device *orig_dev)
|
|
||||||
{
|
|
||||||
struct bat_priv *bat_priv;
|
|
||||||
struct batman_packet *batman_packet;
|
|
||||||
struct batman_if *batman_if;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
batman_if = container_of(ptype, struct batman_if, batman_adv_ptype);
|
|
||||||
skb = skb_share_check(skb, GFP_ATOMIC);
|
|
||||||
|
|
||||||
/* skb was released by skb_share_check() */
|
|
||||||
if (!skb)
|
|
||||||
goto err_out;
|
|
||||||
|
|
||||||
/* packet should hold at least type and version */
|
|
||||||
if (unlikely(!pskb_may_pull(skb, 2)))
|
|
||||||
goto err_free;
|
|
||||||
|
|
||||||
/* expect a valid ethernet header here. */
|
|
||||||
if (unlikely(skb->mac_len != sizeof(struct ethhdr)
|
|
||||||
|| !skb_mac_header(skb)))
|
|
||||||
goto err_free;
|
|
||||||
|
|
||||||
if (!batman_if->soft_iface)
|
|
||||||
goto err_free;
|
|
||||||
|
|
||||||
bat_priv = netdev_priv(batman_if->soft_iface);
|
|
||||||
|
|
||||||
if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE)
|
|
||||||
goto err_free;
|
|
||||||
|
|
||||||
/* discard frames on not active interfaces */
|
|
||||||
if (batman_if->if_status != IF_ACTIVE)
|
|
||||||
goto err_free;
|
|
||||||
|
|
||||||
batman_packet = (struct batman_packet *)skb->data;
|
|
||||||
|
|
||||||
if (batman_packet->version != COMPAT_VERSION) {
|
|
||||||
bat_dbg(DBG_BATMAN, bat_priv,
|
|
||||||
"Drop packet: incompatible batman version (%i)\n",
|
|
||||||
batman_packet->version);
|
|
||||||
goto err_free;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* all receive handlers return whether they received or reused
|
|
||||||
* the supplied skb. if not, we have to free the skb. */
|
|
||||||
|
|
||||||
switch (batman_packet->packet_type) {
|
|
||||||
/* batman originator packet */
|
|
||||||
case BAT_PACKET:
|
|
||||||
ret = recv_bat_packet(skb, batman_if);
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* batman icmp packet */
|
|
||||||
case BAT_ICMP:
|
|
||||||
ret = recv_icmp_packet(skb, batman_if);
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* unicast packet */
|
|
||||||
case BAT_UNICAST:
|
|
||||||
ret = recv_unicast_packet(skb, batman_if);
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* fragmented unicast packet */
|
|
||||||
case BAT_UNICAST_FRAG:
|
|
||||||
ret = recv_ucast_frag_packet(skb, batman_if);
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* broadcast packet */
|
|
||||||
case BAT_BCAST:
|
|
||||||
ret = recv_bcast_packet(skb, batman_if);
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* vis packet */
|
|
||||||
case BAT_VIS:
|
|
||||||
ret = recv_vis_packet(skb, batman_if);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ret = NET_RX_DROP;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret == NET_RX_DROP)
|
|
||||||
kfree_skb(skb);
|
|
||||||
|
|
||||||
/* return NET_RX_SUCCESS in any case as we
|
|
||||||
* most probably dropped the packet for
|
|
||||||
* routing-logical reasons. */
|
|
||||||
|
|
||||||
return NET_RX_SUCCESS;
|
|
||||||
|
|
||||||
err_free:
|
|
||||||
kfree_skb(skb);
|
|
||||||
err_out:
|
|
||||||
return NET_RX_DROP;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct notifier_block hard_if_notifier = {
|
|
||||||
.notifier_call = hard_if_event,
|
|
||||||
};
|
|
@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
|
|
||||||
*
|
|
||||||
* Marek Lindner, Simon Wunderlich
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of version 2 of the GNU General Public
|
|
||||||
* License as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
||||||
* 02110-1301, USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _NET_BATMAN_ADV_HARD_INTERFACE_H_
|
|
||||||
#define _NET_BATMAN_ADV_HARD_INTERFACE_H_
|
|
||||||
|
|
||||||
#define IF_NOT_IN_USE 0
|
|
||||||
#define IF_TO_BE_REMOVED 1
|
|
||||||
#define IF_INACTIVE 2
|
|
||||||
#define IF_ACTIVE 3
|
|
||||||
#define IF_TO_BE_ACTIVATED 4
|
|
||||||
#define IF_I_WANT_YOU 5
|
|
||||||
|
|
||||||
extern struct notifier_block hard_if_notifier;
|
|
||||||
|
|
||||||
struct batman_if *get_batman_if_by_netdev(struct net_device *net_dev);
|
|
||||||
int hardif_enable_interface(struct batman_if *batman_if, char *iface_name);
|
|
||||||
void hardif_disable_interface(struct batman_if *batman_if);
|
|
||||||
void hardif_remove_interfaces(void);
|
|
||||||
int batman_skb_recv(struct sk_buff *skb,
|
|
||||||
struct net_device *dev,
|
|
||||||
struct packet_type *ptype,
|
|
||||||
struct net_device *orig_dev);
|
|
||||||
int hardif_min_mtu(struct net_device *soft_iface);
|
|
||||||
void update_min_mtu(struct net_device *soft_iface);
|
|
||||||
|
|
||||||
static inline void hardif_hold(struct batman_if *batman_if)
|
|
||||||
{
|
|
||||||
atomic_inc(&batman_if->refcnt);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void hardif_put(struct batman_if *batman_if)
|
|
||||||
{
|
|
||||||
if (atomic_dec_and_test(&batman_if->refcnt)) {
|
|
||||||
dev_put(batman_if->net_dev);
|
|
||||||
kfree(batman_if);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* _NET_BATMAN_ADV_HARD_INTERFACE_H_ */
|
|
@ -1,306 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2006-2010 B.A.T.M.A.N. contributors:
|
|
||||||
*
|
|
||||||
* Simon Wunderlich, Marek Lindner
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of version 2 of the GNU General Public
|
|
||||||
* License as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
||||||
* 02110-1301, USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "main.h"
|
|
||||||
#include "hash.h"
|
|
||||||
|
|
||||||
/* clears the hash */
|
|
||||||
static void hash_init(struct hashtable_t *hash)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
hash->elements = 0;
|
|
||||||
|
|
||||||
for (i = 0 ; i < hash->size; i++)
|
|
||||||
hash->table[i] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* remove the hash structure. if hashdata_free_cb != NULL, this function will be
|
|
||||||
* called to remove the elements inside of the hash. if you don't remove the
|
|
||||||
* elements, memory might be leaked. */
|
|
||||||
void hash_delete(struct hashtable_t *hash, hashdata_free_cb free_cb, void *arg)
|
|
||||||
{
|
|
||||||
struct element_t *bucket, *last_bucket;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < hash->size; i++) {
|
|
||||||
bucket = hash->table[i];
|
|
||||||
|
|
||||||
while (bucket != NULL) {
|
|
||||||
if (free_cb != NULL)
|
|
||||||
free_cb(bucket->data, arg);
|
|
||||||
|
|
||||||
last_bucket = bucket;
|
|
||||||
bucket = bucket->next;
|
|
||||||
kfree(last_bucket);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hash_destroy(hash);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* free only the hashtable and the hash itself. */
|
|
||||||
void hash_destroy(struct hashtable_t *hash)
|
|
||||||
{
|
|
||||||
kfree(hash->table);
|
|
||||||
kfree(hash);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* iterate though the hash. First element is selected if an iterator
|
|
||||||
* initialized with HASHIT() is supplied as iter. Use the returned
|
|
||||||
* (or supplied) iterator to access the elements until hash_iterate returns
|
|
||||||
* NULL. */
|
|
||||||
|
|
||||||
struct hash_it_t *hash_iterate(struct hashtable_t *hash,
|
|
||||||
struct hash_it_t *iter)
|
|
||||||
{
|
|
||||||
if (!hash)
|
|
||||||
return NULL;
|
|
||||||
if (!iter)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* sanity checks first (if our bucket got deleted in the last
|
|
||||||
* iteration): */
|
|
||||||
if (iter->bucket != NULL) {
|
|
||||||
if (iter->first_bucket != NULL) {
|
|
||||||
/* we're on the first element and it got removed after
|
|
||||||
* the last iteration. */
|
|
||||||
if ((*iter->first_bucket) != iter->bucket) {
|
|
||||||
/* there are still other elements in the list */
|
|
||||||
if ((*iter->first_bucket) != NULL) {
|
|
||||||
iter->prev_bucket = NULL;
|
|
||||||
iter->bucket = (*iter->first_bucket);
|
|
||||||
iter->first_bucket =
|
|
||||||
&hash->table[iter->index];
|
|
||||||
return iter;
|
|
||||||
} else {
|
|
||||||
iter->bucket = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (iter->prev_bucket != NULL) {
|
|
||||||
/*
|
|
||||||
* we're not on the first element, and the bucket got
|
|
||||||
* removed after the last iteration. the last bucket's
|
|
||||||
* next pointer is not pointing to our actual bucket
|
|
||||||
* anymore. select the next.
|
|
||||||
*/
|
|
||||||
if (iter->prev_bucket->next != iter->bucket)
|
|
||||||
iter->bucket = iter->prev_bucket;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* now as we are sane, select the next one if there is some */
|
|
||||||
if (iter->bucket != NULL) {
|
|
||||||
if (iter->bucket->next != NULL) {
|
|
||||||
iter->prev_bucket = iter->bucket;
|
|
||||||
iter->bucket = iter->bucket->next;
|
|
||||||
iter->first_bucket = NULL;
|
|
||||||
return iter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if not returned yet, we've reached the last one on the index and have
|
|
||||||
* to search forward */
|
|
||||||
iter->index++;
|
|
||||||
/* go through the entries of the hash table */
|
|
||||||
while (iter->index < hash->size) {
|
|
||||||
if ((hash->table[iter->index]) != NULL) {
|
|
||||||
iter->prev_bucket = NULL;
|
|
||||||
iter->bucket = hash->table[iter->index];
|
|
||||||
iter->first_bucket = &hash->table[iter->index];
|
|
||||||
return iter;
|
|
||||||
} else {
|
|
||||||
iter->index++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* nothing to iterate over anymore */
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* allocates and clears the hash */
|
|
||||||
struct hashtable_t *hash_new(int size, hashdata_compare_cb compare,
|
|
||||||
hashdata_choose_cb choose)
|
|
||||||
{
|
|
||||||
struct hashtable_t *hash;
|
|
||||||
|
|
||||||
hash = kmalloc(sizeof(struct hashtable_t) , GFP_ATOMIC);
|
|
||||||
|
|
||||||
if (hash == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
hash->size = size;
|
|
||||||
hash->table = kmalloc(sizeof(struct element_t *) * size, GFP_ATOMIC);
|
|
||||||
|
|
||||||
if (hash->table == NULL) {
|
|
||||||
kfree(hash);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
hash_init(hash);
|
|
||||||
|
|
||||||
hash->compare = compare;
|
|
||||||
hash->choose = choose;
|
|
||||||
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* adds data to the hashtable. returns 0 on success, -1 on error */
|
|
||||||
int hash_add(struct hashtable_t *hash, void *data)
|
|
||||||
{
|
|
||||||
int index;
|
|
||||||
struct element_t *bucket, *prev_bucket = NULL;
|
|
||||||
|
|
||||||
if (!hash)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
index = hash->choose(data, hash->size);
|
|
||||||
bucket = hash->table[index];
|
|
||||||
|
|
||||||
while (bucket != NULL) {
|
|
||||||
if (hash->compare(bucket->data, data))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
prev_bucket = bucket;
|
|
||||||
bucket = bucket->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* found the tail of the list, add new element */
|
|
||||||
bucket = kmalloc(sizeof(struct element_t), GFP_ATOMIC);
|
|
||||||
|
|
||||||
if (bucket == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
bucket->data = data;
|
|
||||||
bucket->next = NULL;
|
|
||||||
|
|
||||||
/* and link it */
|
|
||||||
if (prev_bucket == NULL)
|
|
||||||
hash->table[index] = bucket;
|
|
||||||
else
|
|
||||||
prev_bucket->next = bucket;
|
|
||||||
|
|
||||||
hash->elements++;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* finds data, based on the key in keydata. returns the found data on success,
|
|
||||||
* or NULL on error */
|
|
||||||
void *hash_find(struct hashtable_t *hash, void *keydata)
|
|
||||||
{
|
|
||||||
int index;
|
|
||||||
struct element_t *bucket;
|
|
||||||
|
|
||||||
if (!hash)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
index = hash->choose(keydata , hash->size);
|
|
||||||
bucket = hash->table[index];
|
|
||||||
|
|
||||||
while (bucket != NULL) {
|
|
||||||
if (hash->compare(bucket->data, keydata))
|
|
||||||
return bucket->data;
|
|
||||||
|
|
||||||
bucket = bucket->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* remove bucket (this might be used in hash_iterate() if you already found the
|
|
||||||
* bucket you want to delete and don't need the overhead to find it again with
|
|
||||||
* hash_remove(). But usually, you don't want to use this function, as it
|
|
||||||
* fiddles with hash-internals. */
|
|
||||||
void *hash_remove_bucket(struct hashtable_t *hash, struct hash_it_t *hash_it_t)
|
|
||||||
{
|
|
||||||
void *data_save;
|
|
||||||
|
|
||||||
data_save = hash_it_t->bucket->data;
|
|
||||||
|
|
||||||
if (hash_it_t->prev_bucket != NULL)
|
|
||||||
hash_it_t->prev_bucket->next = hash_it_t->bucket->next;
|
|
||||||
else if (hash_it_t->first_bucket != NULL)
|
|
||||||
(*hash_it_t->first_bucket) = hash_it_t->bucket->next;
|
|
||||||
|
|
||||||
kfree(hash_it_t->bucket);
|
|
||||||
hash->elements--;
|
|
||||||
|
|
||||||
return data_save;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* removes data from hash, if found. returns pointer do data on success, so you
|
|
||||||
* can remove the used structure yourself, or NULL on error . data could be the
|
|
||||||
* structure you use with just the key filled, we just need the key for
|
|
||||||
* comparing. */
|
|
||||||
void *hash_remove(struct hashtable_t *hash, void *data)
|
|
||||||
{
|
|
||||||
struct hash_it_t hash_it_t;
|
|
||||||
|
|
||||||
hash_it_t.index = hash->choose(data, hash->size);
|
|
||||||
hash_it_t.bucket = hash->table[hash_it_t.index];
|
|
||||||
hash_it_t.prev_bucket = NULL;
|
|
||||||
|
|
||||||
while (hash_it_t.bucket != NULL) {
|
|
||||||
if (hash->compare(hash_it_t.bucket->data, data)) {
|
|
||||||
hash_it_t.first_bucket =
|
|
||||||
(hash_it_t.bucket ==
|
|
||||||
hash->table[hash_it_t.index] ?
|
|
||||||
&hash->table[hash_it_t.index] : NULL);
|
|
||||||
return hash_remove_bucket(hash, &hash_it_t);
|
|
||||||
}
|
|
||||||
|
|
||||||
hash_it_t.prev_bucket = hash_it_t.bucket;
|
|
||||||
hash_it_t.bucket = hash_it_t.bucket->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* resize the hash, returns the pointer to the new hash or NULL on
|
|
||||||
* error. removes the old hash on success. */
|
|
||||||
struct hashtable_t *hash_resize(struct hashtable_t *hash, int size)
|
|
||||||
{
|
|
||||||
struct hashtable_t *new_hash;
|
|
||||||
struct element_t *bucket;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* initialize a new hash with the new size */
|
|
||||||
new_hash = hash_new(size, hash->compare, hash->choose);
|
|
||||||
|
|
||||||
if (new_hash == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* copy the elements */
|
|
||||||
for (i = 0; i < hash->size; i++) {
|
|
||||||
bucket = hash->table[i];
|
|
||||||
|
|
||||||
while (bucket != NULL) {
|
|
||||||
hash_add(new_hash, bucket->data);
|
|
||||||
bucket = bucket->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* remove hash and eventual overflow buckets but not the content
|
|
||||||
* itself. */
|
|
||||||
hash_delete(hash, NULL, NULL);
|
|
||||||
|
|
||||||
return new_hash;
|
|
||||||
}
|
|
@ -1,100 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2006-2010 B.A.T.M.A.N. contributors:
|
|
||||||
*
|
|
||||||
* Simon Wunderlich, Marek Lindner
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of version 2 of the GNU General Public
|
|
||||||
* License as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
||||||
* 02110-1301, USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _NET_BATMAN_ADV_HASH_H_
|
|
||||||
#define _NET_BATMAN_ADV_HASH_H_
|
|
||||||
|
|
||||||
#define HASHIT(name) struct hash_it_t name = { \
|
|
||||||
.index = -1, .bucket = NULL, \
|
|
||||||
.prev_bucket = NULL, \
|
|
||||||
.first_bucket = NULL }
|
|
||||||
|
|
||||||
|
|
||||||
typedef int (*hashdata_compare_cb)(void *, void *);
|
|
||||||
typedef int (*hashdata_choose_cb)(void *, int);
|
|
||||||
typedef void (*hashdata_free_cb)(void *, void *);
|
|
||||||
|
|
||||||
struct element_t {
|
|
||||||
void *data; /* pointer to the data */
|
|
||||||
struct element_t *next; /* overflow bucket pointer */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct hash_it_t {
|
|
||||||
int index;
|
|
||||||
struct element_t *bucket;
|
|
||||||
struct element_t *prev_bucket;
|
|
||||||
struct element_t **first_bucket;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct hashtable_t {
|
|
||||||
struct element_t **table; /* the hashtable itself, with the buckets */
|
|
||||||
int elements; /* number of elements registered */
|
|
||||||
int size; /* size of hashtable */
|
|
||||||
hashdata_compare_cb compare;/* callback to a compare function. should
|
|
||||||
* compare 2 element datas for their keys,
|
|
||||||
* return 0 if same and not 0 if not
|
|
||||||
* same */
|
|
||||||
hashdata_choose_cb choose; /* the hashfunction, should return an index
|
|
||||||
* based on the key in the data of the first
|
|
||||||
* argument and the size the second */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* allocates and clears the hash */
|
|
||||||
struct hashtable_t *hash_new(int size, hashdata_compare_cb compare,
|
|
||||||
hashdata_choose_cb choose);
|
|
||||||
|
|
||||||
/* remove bucket (this might be used in hash_iterate() if you already found the
|
|
||||||
* bucket you want to delete and don't need the overhead to find it again with
|
|
||||||
* hash_remove(). But usually, you don't want to use this function, as it
|
|
||||||
* fiddles with hash-internals. */
|
|
||||||
void *hash_remove_bucket(struct hashtable_t *hash, struct hash_it_t *hash_it_t);
|
|
||||||
|
|
||||||
/* remove the hash structure. if hashdata_free_cb != NULL, this function will be
|
|
||||||
* called to remove the elements inside of the hash. if you don't remove the
|
|
||||||
* elements, memory might be leaked. */
|
|
||||||
void hash_delete(struct hashtable_t *hash, hashdata_free_cb free_cb, void *arg);
|
|
||||||
|
|
||||||
/* free only the hashtable and the hash itself. */
|
|
||||||
void hash_destroy(struct hashtable_t *hash);
|
|
||||||
|
|
||||||
/* adds data to the hashtable. returns 0 on success, -1 on error */
|
|
||||||
int hash_add(struct hashtable_t *hash, void *data);
|
|
||||||
|
|
||||||
/* removes data from hash, if found. returns pointer do data on success, so you
|
|
||||||
* can remove the used structure yourself, or NULL on error . data could be the
|
|
||||||
* structure you use with just the key filled, we just need the key for
|
|
||||||
* comparing. */
|
|
||||||
void *hash_remove(struct hashtable_t *hash, void *data);
|
|
||||||
|
|
||||||
/* finds data, based on the key in keydata. returns the found data on success,
|
|
||||||
* or NULL on error */
|
|
||||||
void *hash_find(struct hashtable_t *hash, void *keydata);
|
|
||||||
|
|
||||||
/* resize the hash, returns the pointer to the new hash or NULL on
|
|
||||||
* error. removes the old hash on success */
|
|
||||||
struct hashtable_t *hash_resize(struct hashtable_t *hash, int size);
|
|
||||||
|
|
||||||
/* iterate though the hash. first element is selected with iter_in NULL. use
|
|
||||||
* the returned iterator to access the elements until hash_it_t returns NULL. */
|
|
||||||
struct hash_it_t *hash_iterate(struct hashtable_t *hash,
|
|
||||||
struct hash_it_t *iter_in);
|
|
||||||
|
|
||||||
#endif /* _NET_BATMAN_ADV_HASH_H_ */
|
|
@ -1,359 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
|
|
||||||
*
|
|
||||||
* Marek Lindner
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of version 2 of the GNU General Public
|
|
||||||
* License as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
||||||
* 02110-1301, USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "main.h"
|
|
||||||
#include <linux/debugfs.h>
|
|
||||||
#include <linux/slab.h>
|
|
||||||
#include "icmp_socket.h"
|
|
||||||
#include "send.h"
|
|
||||||
#include "types.h"
|
|
||||||
#include "hash.h"
|
|
||||||
#include "hard-interface.h"
|
|
||||||
|
|
||||||
|
|
||||||
static struct socket_client *socket_client_hash[256];
|
|
||||||
|
|
||||||
static void bat_socket_add_packet(struct socket_client *socket_client,
|
|
||||||
struct icmp_packet_rr *icmp_packet,
|
|
||||||
size_t icmp_len);
|
|
||||||
|
|
||||||
void bat_socket_init(void)
|
|
||||||
{
|
|
||||||
memset(socket_client_hash, 0, sizeof(socket_client_hash));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int bat_socket_open(struct inode *inode, struct file *file)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
struct socket_client *socket_client;
|
|
||||||
|
|
||||||
nonseekable_open(inode, file);
|
|
||||||
|
|
||||||
socket_client = kmalloc(sizeof(struct socket_client), GFP_KERNEL);
|
|
||||||
|
|
||||||
if (!socket_client)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(socket_client_hash); i++) {
|
|
||||||
if (!socket_client_hash[i]) {
|
|
||||||
socket_client_hash[i] = socket_client;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i == ARRAY_SIZE(socket_client_hash)) {
|
|
||||||
pr_err("Error - can't add another packet client: "
|
|
||||||
"maximum number of clients reached\n");
|
|
||||||
kfree(socket_client);
|
|
||||||
return -EXFULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
INIT_LIST_HEAD(&socket_client->queue_list);
|
|
||||||
socket_client->queue_len = 0;
|
|
||||||
socket_client->index = i;
|
|
||||||
socket_client->bat_priv = inode->i_private;
|
|
||||||
spin_lock_init(&socket_client->lock);
|
|
||||||
init_waitqueue_head(&socket_client->queue_wait);
|
|
||||||
|
|
||||||
file->private_data = socket_client;
|
|
||||||
|
|
||||||
inc_module_count();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int bat_socket_release(struct inode *inode, struct file *file)
|
|
||||||
{
|
|
||||||
struct socket_client *socket_client = file->private_data;
|
|
||||||
struct socket_packet *socket_packet;
|
|
||||||
struct list_head *list_pos, *list_pos_tmp;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&socket_client->lock, flags);
|
|
||||||
|
|
||||||
/* for all packets in the queue ... */
|
|
||||||
list_for_each_safe(list_pos, list_pos_tmp, &socket_client->queue_list) {
|
|
||||||
socket_packet = list_entry(list_pos,
|
|
||||||
struct socket_packet, list);
|
|
||||||
|
|
||||||
list_del(list_pos);
|
|
||||||
kfree(socket_packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
socket_client_hash[socket_client->index] = NULL;
|
|
||||||
spin_unlock_irqrestore(&socket_client->lock, flags);
|
|
||||||
|
|
||||||
kfree(socket_client);
|
|
||||||
dec_module_count();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t bat_socket_read(struct file *file, char __user *buf,
|
|
||||||
size_t count, loff_t *ppos)
|
|
||||||
{
|
|
||||||
struct socket_client *socket_client = file->private_data;
|
|
||||||
struct socket_packet *socket_packet;
|
|
||||||
size_t packet_len;
|
|
||||||
int error;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
if ((file->f_flags & O_NONBLOCK) && (socket_client->queue_len == 0))
|
|
||||||
return -EAGAIN;
|
|
||||||
|
|
||||||
if ((!buf) || (count < sizeof(struct icmp_packet)))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (!access_ok(VERIFY_WRITE, buf, count))
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
error = wait_event_interruptible(socket_client->queue_wait,
|
|
||||||
socket_client->queue_len);
|
|
||||||
|
|
||||||
if (error)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&socket_client->lock, flags);
|
|
||||||
|
|
||||||
socket_packet = list_first_entry(&socket_client->queue_list,
|
|
||||||
struct socket_packet, list);
|
|
||||||
list_del(&socket_packet->list);
|
|
||||||
socket_client->queue_len--;
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&socket_client->lock, flags);
|
|
||||||
|
|
||||||
error = __copy_to_user(buf, &socket_packet->icmp_packet,
|
|
||||||
socket_packet->icmp_len);
|
|
||||||
|
|
||||||
packet_len = socket_packet->icmp_len;
|
|
||||||
kfree(socket_packet);
|
|
||||||
|
|
||||||
if (error)
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
return packet_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t bat_socket_write(struct file *file, const char __user *buff,
|
|
||||||
size_t len, loff_t *off)
|
|
||||||
{
|
|
||||||
struct socket_client *socket_client = file->private_data;
|
|
||||||
struct bat_priv *bat_priv = socket_client->bat_priv;
|
|
||||||
struct sk_buff *skb;
|
|
||||||
struct icmp_packet_rr *icmp_packet;
|
|
||||||
|
|
||||||
struct orig_node *orig_node;
|
|
||||||
struct batman_if *batman_if;
|
|
||||||
size_t packet_len = sizeof(struct icmp_packet);
|
|
||||||
uint8_t dstaddr[ETH_ALEN];
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
if (len < sizeof(struct icmp_packet)) {
|
|
||||||
bat_dbg(DBG_BATMAN, bat_priv,
|
|
||||||
"Error - can't send packet from char device: "
|
|
||||||
"invalid packet size\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!bat_priv->primary_if)
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
if (len >= sizeof(struct icmp_packet_rr))
|
|
||||||
packet_len = sizeof(struct icmp_packet_rr);
|
|
||||||
|
|
||||||
skb = dev_alloc_skb(packet_len + sizeof(struct ethhdr));
|
|
||||||
if (!skb)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
skb_reserve(skb, sizeof(struct ethhdr));
|
|
||||||
icmp_packet = (struct icmp_packet_rr *)skb_put(skb, packet_len);
|
|
||||||
|
|
||||||
if (!access_ok(VERIFY_READ, buff, packet_len)) {
|
|
||||||
len = -EFAULT;
|
|
||||||
goto free_skb;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (__copy_from_user(icmp_packet, buff, packet_len)) {
|
|
||||||
len = -EFAULT;
|
|
||||||
goto free_skb;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (icmp_packet->packet_type != BAT_ICMP) {
|
|
||||||
bat_dbg(DBG_BATMAN, bat_priv,
|
|
||||||
"Error - can't send packet from char device: "
|
|
||||||
"got bogus packet type (expected: BAT_ICMP)\n");
|
|
||||||
len = -EINVAL;
|
|
||||||
goto free_skb;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (icmp_packet->msg_type != ECHO_REQUEST) {
|
|
||||||
bat_dbg(DBG_BATMAN, bat_priv,
|
|
||||||
"Error - can't send packet from char device: "
|
|
||||||
"got bogus message type (expected: ECHO_REQUEST)\n");
|
|
||||||
len = -EINVAL;
|
|
||||||
goto free_skb;
|
|
||||||
}
|
|
||||||
|
|
||||||
icmp_packet->uid = socket_client->index;
|
|
||||||
|
|
||||||
if (icmp_packet->version != COMPAT_VERSION) {
|
|
||||||
icmp_packet->msg_type = PARAMETER_PROBLEM;
|
|
||||||
icmp_packet->ttl = COMPAT_VERSION;
|
|
||||||
bat_socket_add_packet(socket_client, icmp_packet, packet_len);
|
|
||||||
goto free_skb;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE)
|
|
||||||
goto dst_unreach;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&bat_priv->orig_hash_lock, flags);
|
|
||||||
orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash,
|
|
||||||
icmp_packet->dst));
|
|
||||||
|
|
||||||
if (!orig_node)
|
|
||||||
goto unlock;
|
|
||||||
|
|
||||||
if (!orig_node->router)
|
|
||||||
goto unlock;
|
|
||||||
|
|
||||||
batman_if = orig_node->router->if_incoming;
|
|
||||||
memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
|
|
||||||
|
|
||||||
if (!batman_if)
|
|
||||||
goto dst_unreach;
|
|
||||||
|
|
||||||
if (batman_if->if_status != IF_ACTIVE)
|
|
||||||
goto dst_unreach;
|
|
||||||
|
|
||||||
memcpy(icmp_packet->orig,
|
|
||||||
bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
|
|
||||||
|
|
||||||
if (packet_len == sizeof(struct icmp_packet_rr))
|
|
||||||
memcpy(icmp_packet->rr, batman_if->net_dev->dev_addr, ETH_ALEN);
|
|
||||||
|
|
||||||
|
|
||||||
send_skb_packet(skb, batman_if, dstaddr);
|
|
||||||
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
unlock:
|
|
||||||
spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
|
|
||||||
dst_unreach:
|
|
||||||
icmp_packet->msg_type = DESTINATION_UNREACHABLE;
|
|
||||||
bat_socket_add_packet(socket_client, icmp_packet, packet_len);
|
|
||||||
free_skb:
|
|
||||||
kfree_skb(skb);
|
|
||||||
out:
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned int bat_socket_poll(struct file *file, poll_table *wait)
|
|
||||||
{
|
|
||||||
struct socket_client *socket_client = file->private_data;
|
|
||||||
|
|
||||||
poll_wait(file, &socket_client->queue_wait, wait);
|
|
||||||
|
|
||||||
if (socket_client->queue_len > 0)
|
|
||||||
return POLLIN | POLLRDNORM;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct file_operations fops = {
|
|
||||||
.owner = THIS_MODULE,
|
|
||||||
.open = bat_socket_open,
|
|
||||||
.release = bat_socket_release,
|
|
||||||
.read = bat_socket_read,
|
|
||||||
.write = bat_socket_write,
|
|
||||||
.poll = bat_socket_poll,
|
|
||||||
.llseek = no_llseek,
|
|
||||||
};
|
|
||||||
|
|
||||||
int bat_socket_setup(struct bat_priv *bat_priv)
|
|
||||||
{
|
|
||||||
struct dentry *d;
|
|
||||||
|
|
||||||
if (!bat_priv->debug_dir)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
d = debugfs_create_file(ICMP_SOCKET, S_IFREG | S_IWUSR | S_IRUSR,
|
|
||||||
bat_priv->debug_dir, bat_priv, &fops);
|
|
||||||
if (d)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
err:
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void bat_socket_add_packet(struct socket_client *socket_client,
|
|
||||||
struct icmp_packet_rr *icmp_packet,
|
|
||||||
size_t icmp_len)
|
|
||||||
{
|
|
||||||
struct socket_packet *socket_packet;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
socket_packet = kmalloc(sizeof(struct socket_packet), GFP_ATOMIC);
|
|
||||||
|
|
||||||
if (!socket_packet)
|
|
||||||
return;
|
|
||||||
|
|
||||||
INIT_LIST_HEAD(&socket_packet->list);
|
|
||||||
memcpy(&socket_packet->icmp_packet, icmp_packet, icmp_len);
|
|
||||||
socket_packet->icmp_len = icmp_len;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&socket_client->lock, flags);
|
|
||||||
|
|
||||||
/* while waiting for the lock the socket_client could have been
|
|
||||||
* deleted */
|
|
||||||
if (!socket_client_hash[icmp_packet->uid]) {
|
|
||||||
spin_unlock_irqrestore(&socket_client->lock, flags);
|
|
||||||
kfree(socket_packet);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
list_add_tail(&socket_packet->list, &socket_client->queue_list);
|
|
||||||
socket_client->queue_len++;
|
|
||||||
|
|
||||||
if (socket_client->queue_len > 100) {
|
|
||||||
socket_packet = list_first_entry(&socket_client->queue_list,
|
|
||||||
struct socket_packet, list);
|
|
||||||
|
|
||||||
list_del(&socket_packet->list);
|
|
||||||
kfree(socket_packet);
|
|
||||||
socket_client->queue_len--;
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&socket_client->lock, flags);
|
|
||||||
|
|
||||||
wake_up(&socket_client->queue_wait);
|
|
||||||
}
|
|
||||||
|
|
||||||
void bat_socket_receive_packet(struct icmp_packet_rr *icmp_packet,
|
|
||||||
size_t icmp_len)
|
|
||||||
{
|
|
||||||
struct socket_client *hash = socket_client_hash[icmp_packet->uid];
|
|
||||||
|
|
||||||
if (hash)
|
|
||||||
bat_socket_add_packet(hash, icmp_packet, icmp_len);
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
|
|
||||||
*
|
|
||||||
* Marek Lindner
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of version 2 of the GNU General Public
|
|
||||||
* License as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
||||||
* 02110-1301, USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _NET_BATMAN_ADV_ICMP_SOCKET_H_
|
|
||||||
#define _NET_BATMAN_ADV_ICMP_SOCKET_H_
|
|
||||||
|
|
||||||
#include "types.h"
|
|
||||||
|
|
||||||
#define ICMP_SOCKET "socket"
|
|
||||||
|
|
||||||
void bat_socket_init(void);
|
|
||||||
int bat_socket_setup(struct bat_priv *bat_priv);
|
|
||||||
void bat_socket_receive_packet(struct icmp_packet_rr *icmp_packet,
|
|
||||||
size_t icmp_len);
|
|
||||||
|
|
||||||
#endif /* _NET_BATMAN_ADV_ICMP_SOCKET_H_ */
|
|
@ -1,217 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
|
|
||||||
*
|
|
||||||
* Marek Lindner, Simon Wunderlich
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of version 2 of the GNU General Public
|
|
||||||
* License as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
||||||
* 02110-1301, USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "main.h"
|
|
||||||
#include "bat_sysfs.h"
|
|
||||||
#include "bat_debugfs.h"
|
|
||||||
#include "routing.h"
|
|
||||||
#include "send.h"
|
|
||||||
#include "originator.h"
|
|
||||||
#include "soft-interface.h"
|
|
||||||
#include "icmp_socket.h"
|
|
||||||
#include "translation-table.h"
|
|
||||||
#include "hard-interface.h"
|
|
||||||
#include "types.h"
|
|
||||||
#include "vis.h"
|
|
||||||
#include "hash.h"
|
|
||||||
|
|
||||||
struct list_head if_list;
|
|
||||||
|
|
||||||
unsigned char broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
|
||||||
|
|
||||||
struct workqueue_struct *bat_event_workqueue;
|
|
||||||
|
|
||||||
static int __init batman_init(void)
|
|
||||||
{
|
|
||||||
INIT_LIST_HEAD(&if_list);
|
|
||||||
|
|
||||||
/* the name should not be longer than 10 chars - see
|
|
||||||
* http://lwn.net/Articles/23634/ */
|
|
||||||
bat_event_workqueue = create_singlethread_workqueue("bat_events");
|
|
||||||
|
|
||||||
if (!bat_event_workqueue)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
bat_socket_init();
|
|
||||||
debugfs_init();
|
|
||||||
|
|
||||||
register_netdevice_notifier(&hard_if_notifier);
|
|
||||||
|
|
||||||
pr_info("B.A.T.M.A.N. advanced %s%s (compatibility version %i) "
|
|
||||||
"loaded\n", SOURCE_VERSION, REVISION_VERSION_STR,
|
|
||||||
COMPAT_VERSION);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __exit batman_exit(void)
|
|
||||||
{
|
|
||||||
debugfs_destroy();
|
|
||||||
unregister_netdevice_notifier(&hard_if_notifier);
|
|
||||||
hardif_remove_interfaces();
|
|
||||||
|
|
||||||
flush_workqueue(bat_event_workqueue);
|
|
||||||
destroy_workqueue(bat_event_workqueue);
|
|
||||||
bat_event_workqueue = NULL;
|
|
||||||
|
|
||||||
rcu_barrier();
|
|
||||||
}
|
|
||||||
|
|
||||||
int mesh_init(struct net_device *soft_iface)
|
|
||||||
{
|
|
||||||
struct bat_priv *bat_priv = netdev_priv(soft_iface);
|
|
||||||
|
|
||||||
spin_lock_init(&bat_priv->orig_hash_lock);
|
|
||||||
spin_lock_init(&bat_priv->forw_bat_list_lock);
|
|
||||||
spin_lock_init(&bat_priv->forw_bcast_list_lock);
|
|
||||||
spin_lock_init(&bat_priv->hna_lhash_lock);
|
|
||||||
spin_lock_init(&bat_priv->hna_ghash_lock);
|
|
||||||
spin_lock_init(&bat_priv->vis_hash_lock);
|
|
||||||
spin_lock_init(&bat_priv->vis_list_lock);
|
|
||||||
|
|
||||||
INIT_HLIST_HEAD(&bat_priv->forw_bat_list);
|
|
||||||
INIT_HLIST_HEAD(&bat_priv->forw_bcast_list);
|
|
||||||
|
|
||||||
if (originator_init(bat_priv) < 1)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
if (hna_local_init(bat_priv) < 1)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
if (hna_global_init(bat_priv) < 1)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
hna_local_add(soft_iface, soft_iface->dev_addr);
|
|
||||||
|
|
||||||
if (vis_init(bat_priv) < 1)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
atomic_set(&bat_priv->mesh_state, MESH_ACTIVE);
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
err:
|
|
||||||
pr_err("Unable to allocate memory for mesh information structures: "
|
|
||||||
"out of mem ?\n");
|
|
||||||
mesh_free(soft_iface);
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
end:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mesh_free(struct net_device *soft_iface)
|
|
||||||
{
|
|
||||||
struct bat_priv *bat_priv = netdev_priv(soft_iface);
|
|
||||||
|
|
||||||
atomic_set(&bat_priv->mesh_state, MESH_DEACTIVATING);
|
|
||||||
|
|
||||||
purge_outstanding_packets(bat_priv, NULL);
|
|
||||||
|
|
||||||
vis_quit(bat_priv);
|
|
||||||
|
|
||||||
originator_free(bat_priv);
|
|
||||||
|
|
||||||
hna_local_free(bat_priv);
|
|
||||||
hna_global_free(bat_priv);
|
|
||||||
|
|
||||||
atomic_set(&bat_priv->mesh_state, MESH_INACTIVE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void inc_module_count(void)
|
|
||||||
{
|
|
||||||
try_module_get(THIS_MODULE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void dec_module_count(void)
|
|
||||||
{
|
|
||||||
module_put(THIS_MODULE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* returns 1 if they are the same originator */
|
|
||||||
|
|
||||||
int compare_orig(void *data1, void *data2)
|
|
||||||
{
|
|
||||||
return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* hashfunction to choose an entry in a hash table of given size */
|
|
||||||
/* hash algorithm from http://en.wikipedia.org/wiki/Hash_table */
|
|
||||||
int choose_orig(void *data, int32_t size)
|
|
||||||
{
|
|
||||||
unsigned char *key = data;
|
|
||||||
uint32_t hash = 0;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
for (i = 0; i < 6; i++) {
|
|
||||||
hash += key[i];
|
|
||||||
hash += (hash << 10);
|
|
||||||
hash ^= (hash >> 6);
|
|
||||||
}
|
|
||||||
|
|
||||||
hash += (hash << 3);
|
|
||||||
hash ^= (hash >> 11);
|
|
||||||
hash += (hash << 15);
|
|
||||||
|
|
||||||
return hash % size;
|
|
||||||
}
|
|
||||||
|
|
||||||
int is_my_mac(uint8_t *addr)
|
|
||||||
{
|
|
||||||
struct batman_if *batman_if;
|
|
||||||
|
|
||||||
rcu_read_lock();
|
|
||||||
list_for_each_entry_rcu(batman_if, &if_list, list) {
|
|
||||||
if (batman_if->if_status != IF_ACTIVE)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (compare_orig(batman_if->net_dev->dev_addr, addr)) {
|
|
||||||
rcu_read_unlock();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rcu_read_unlock();
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
int is_bcast(uint8_t *addr)
|
|
||||||
{
|
|
||||||
return (addr[0] == (uint8_t)0xff) && (addr[1] == (uint8_t)0xff);
|
|
||||||
}
|
|
||||||
|
|
||||||
int is_mcast(uint8_t *addr)
|
|
||||||
{
|
|
||||||
return *addr & 0x01;
|
|
||||||
}
|
|
||||||
|
|
||||||
module_init(batman_init);
|
|
||||||
module_exit(batman_exit);
|
|
||||||
|
|
||||||
MODULE_LICENSE("GPL");
|
|
||||||
|
|
||||||
MODULE_AUTHOR(DRIVER_AUTHOR);
|
|
||||||
MODULE_DESCRIPTION(DRIVER_DESC);
|
|
||||||
MODULE_SUPPORTED_DEVICE(DRIVER_DEVICE);
|
|
||||||
#ifdef REVISION_VERSION
|
|
||||||
MODULE_VERSION(SOURCE_VERSION "-" REVISION_VERSION);
|
|
||||||
#else
|
|
||||||
MODULE_VERSION(SOURCE_VERSION);
|
|
||||||
#endif
|
|
@ -1,183 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
|
|
||||||
*
|
|
||||||
* Marek Lindner, Simon Wunderlich
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of version 2 of the GNU General Public
|
|
||||||
* License as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
||||||
* 02110-1301, USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _NET_BATMAN_ADV_MAIN_H_
|
|
||||||
#define _NET_BATMAN_ADV_MAIN_H_
|
|
||||||
|
|
||||||
/* Kernel Programming */
|
|
||||||
#define LINUX
|
|
||||||
|
|
||||||
#define DRIVER_AUTHOR "Marek Lindner <lindner_marek@yahoo.de>, " \
|
|
||||||
"Simon Wunderlich <siwu@hrz.tu-chemnitz.de>"
|
|
||||||
#define DRIVER_DESC "B.A.T.M.A.N. advanced"
|
|
||||||
#define DRIVER_DEVICE "batman-adv"
|
|
||||||
|
|
||||||
#define SOURCE_VERSION "next"
|
|
||||||
|
|
||||||
|
|
||||||
/* B.A.T.M.A.N. parameters */
|
|
||||||
|
|
||||||
#define TQ_MAX_VALUE 255
|
|
||||||
#define JITTER 20
|
|
||||||
#define TTL 50 /* Time To Live of broadcast messages */
|
|
||||||
|
|
||||||
#define PURGE_TIMEOUT 200 /* purge originators after time in seconds if no
|
|
||||||
* valid packet comes in -> TODO: check
|
|
||||||
* influence on TQ_LOCAL_WINDOW_SIZE */
|
|
||||||
#define LOCAL_HNA_TIMEOUT 3600 /* in seconds */
|
|
||||||
|
|
||||||
#define TQ_LOCAL_WINDOW_SIZE 64 /* sliding packet range of received originator
|
|
||||||
* messages in squence numbers (should be a
|
|
||||||
* multiple of our word size) */
|
|
||||||
#define TQ_GLOBAL_WINDOW_SIZE 5
|
|
||||||
#define TQ_LOCAL_BIDRECT_SEND_MINIMUM 1
|
|
||||||
#define TQ_LOCAL_BIDRECT_RECV_MINIMUM 1
|
|
||||||
#define TQ_TOTAL_BIDRECT_LIMIT 1
|
|
||||||
|
|
||||||
#define TQ_HOP_PENALTY 10
|
|
||||||
|
|
||||||
#define NUM_WORDS (TQ_LOCAL_WINDOW_SIZE / WORD_BIT_SIZE)
|
|
||||||
|
|
||||||
#define PACKBUFF_SIZE 2000
|
|
||||||
#define LOG_BUF_LEN 8192 /* has to be a power of 2 */
|
|
||||||
|
|
||||||
#define VIS_INTERVAL 5000 /* 5 seconds */
|
|
||||||
|
|
||||||
/* how much worse secondary interfaces may be to
|
|
||||||
* to be considered as bonding candidates */
|
|
||||||
|
|
||||||
#define BONDING_TQ_THRESHOLD 50
|
|
||||||
|
|
||||||
#define MAX_AGGREGATION_BYTES 512 /* should not be bigger than 512 bytes or
|
|
||||||
* change the size of
|
|
||||||
* forw_packet->direct_link_flags */
|
|
||||||
#define MAX_AGGREGATION_MS 100
|
|
||||||
|
|
||||||
#define RESET_PROTECTION_MS 30000
|
|
||||||
#define EXPECTED_SEQNO_RANGE 65536
|
|
||||||
/* don't reset again within 30 seconds */
|
|
||||||
|
|
||||||
#define MESH_INACTIVE 0
|
|
||||||
#define MESH_ACTIVE 1
|
|
||||||
#define MESH_DEACTIVATING 2
|
|
||||||
|
|
||||||
#define BCAST_QUEUE_LEN 256
|
|
||||||
#define BATMAN_QUEUE_LEN 256
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Debug Messages
|
|
||||||
*/
|
|
||||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt /* Append 'batman-adv: ' before
|
|
||||||
* kernel messages */
|
|
||||||
|
|
||||||
#define DBG_BATMAN 1 /* all messages related to routing / flooding /
|
|
||||||
* broadcasting / etc */
|
|
||||||
#define DBG_ROUTES 2 /* route or hna added / changed / deleted */
|
|
||||||
#define DBG_ALL 3
|
|
||||||
|
|
||||||
#define LOG_BUF_LEN 8192 /* has to be a power of 2 */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Vis
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* #define VIS_SUBCLUSTERS_DISABLED */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Kernel headers
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/mutex.h> /* mutex */
|
|
||||||
#include <linux/module.h> /* needed by all modules */
|
|
||||||
#include <linux/netdevice.h> /* netdevice */
|
|
||||||
#include <linux/if_ether.h> /* ethernet header */
|
|
||||||
#include <linux/poll.h> /* poll_table */
|
|
||||||
#include <linux/kthread.h> /* kernel threads */
|
|
||||||
#include <linux/pkt_sched.h> /* schedule types */
|
|
||||||
#include <linux/workqueue.h> /* workqueue */
|
|
||||||
#include <linux/slab.h>
|
|
||||||
#include <net/sock.h> /* struct sock */
|
|
||||||
#include <linux/jiffies.h>
|
|
||||||
#include <linux/seq_file.h>
|
|
||||||
#include "types.h"
|
|
||||||
|
|
||||||
#ifndef REVISION_VERSION
|
|
||||||
#define REVISION_VERSION_STR ""
|
|
||||||
#else
|
|
||||||
#define REVISION_VERSION_STR " "REVISION_VERSION
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern struct list_head if_list;
|
|
||||||
|
|
||||||
extern unsigned char broadcast_addr[];
|
|
||||||
extern struct workqueue_struct *bat_event_workqueue;
|
|
||||||
|
|
||||||
int mesh_init(struct net_device *soft_iface);
|
|
||||||
void mesh_free(struct net_device *soft_iface);
|
|
||||||
void inc_module_count(void);
|
|
||||||
void dec_module_count(void);
|
|
||||||
int compare_orig(void *data1, void *data2);
|
|
||||||
int choose_orig(void *data, int32_t size);
|
|
||||||
int is_my_mac(uint8_t *addr);
|
|
||||||
int is_bcast(uint8_t *addr);
|
|
||||||
int is_mcast(uint8_t *addr);
|
|
||||||
|
|
||||||
#ifdef CONFIG_BATMAN_ADV_DEBUG
|
|
||||||
int debug_log(struct bat_priv *bat_priv, char *fmt, ...);
|
|
||||||
|
|
||||||
#define bat_dbg(type, bat_priv, fmt, arg...) \
|
|
||||||
do { \
|
|
||||||
if (atomic_read(&bat_priv->log_level) & type) \
|
|
||||||
debug_log(bat_priv, fmt, ## arg); \
|
|
||||||
} \
|
|
||||||
while (0)
|
|
||||||
#else /* !CONFIG_BATMAN_ADV_DEBUG */
|
|
||||||
static inline void bat_dbg(char type __attribute__((unused)),
|
|
||||||
struct bat_priv *bat_priv __attribute__((unused)),
|
|
||||||
char *fmt __attribute__((unused)), ...)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define bat_warning(net_dev, fmt, arg...) \
|
|
||||||
do { \
|
|
||||||
struct net_device *_netdev = (net_dev); \
|
|
||||||
struct bat_priv *_batpriv = netdev_priv(_netdev); \
|
|
||||||
bat_dbg(DBG_ALL, _batpriv, fmt, ## arg); \
|
|
||||||
pr_warning("%s: " fmt, _netdev->name, ## arg); \
|
|
||||||
} while (0)
|
|
||||||
#define bat_info(net_dev, fmt, arg...) \
|
|
||||||
do { \
|
|
||||||
struct net_device *_netdev = (net_dev); \
|
|
||||||
struct bat_priv *_batpriv = netdev_priv(_netdev); \
|
|
||||||
bat_dbg(DBG_ALL, _batpriv, fmt, ## arg); \
|
|
||||||
pr_info("%s: " fmt, _netdev->name, ## arg); \
|
|
||||||
} while (0)
|
|
||||||
#define bat_err(net_dev, fmt, arg...) \
|
|
||||||
do { \
|
|
||||||
struct net_device *_netdev = (net_dev); \
|
|
||||||
struct bat_priv *_batpriv = netdev_priv(_netdev); \
|
|
||||||
bat_dbg(DBG_ALL, _batpriv, fmt, ## arg); \
|
|
||||||
pr_err("%s: " fmt, _netdev->name, ## arg); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#endif /* _NET_BATMAN_ADV_MAIN_H_ */
|
|
@ -1,533 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2009-2010 B.A.T.M.A.N. contributors:
|
|
||||||
*
|
|
||||||
* Marek Lindner, Simon Wunderlich
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of version 2 of the GNU General Public
|
|
||||||
* License as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
||||||
* 02110-1301, USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* increase the reference counter for this originator */
|
|
||||||
|
|
||||||
#include "main.h"
|
|
||||||
#include "originator.h"
|
|
||||||
#include "hash.h"
|
|
||||||
#include "translation-table.h"
|
|
||||||
#include "routing.h"
|
|
||||||
#include "hard-interface.h"
|
|
||||||
#include "unicast.h"
|
|
||||||
|
|
||||||
static void purge_orig(struct work_struct *work);
|
|
||||||
|
|
||||||
static void start_purge_timer(struct bat_priv *bat_priv)
|
|
||||||
{
|
|
||||||
INIT_DELAYED_WORK(&bat_priv->orig_work, purge_orig);
|
|
||||||
queue_delayed_work(bat_event_workqueue, &bat_priv->orig_work, 1 * HZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
int originator_init(struct bat_priv *bat_priv)
|
|
||||||
{
|
|
||||||
unsigned long flags;
|
|
||||||
if (bat_priv->orig_hash)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&bat_priv->orig_hash_lock, flags);
|
|
||||||
bat_priv->orig_hash = hash_new(128, compare_orig, choose_orig);
|
|
||||||
|
|
||||||
if (!bat_priv->orig_hash)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
|
|
||||||
start_purge_timer(bat_priv);
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
err:
|
|
||||||
spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct neigh_node *
|
|
||||||
create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node,
|
|
||||||
uint8_t *neigh, struct batman_if *if_incoming)
|
|
||||||
{
|
|
||||||
struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
|
|
||||||
struct neigh_node *neigh_node;
|
|
||||||
|
|
||||||
bat_dbg(DBG_BATMAN, bat_priv,
|
|
||||||
"Creating new last-hop neighbor of originator\n");
|
|
||||||
|
|
||||||
neigh_node = kzalloc(sizeof(struct neigh_node), GFP_ATOMIC);
|
|
||||||
if (!neigh_node)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
INIT_LIST_HEAD(&neigh_node->list);
|
|
||||||
|
|
||||||
memcpy(neigh_node->addr, neigh, ETH_ALEN);
|
|
||||||
neigh_node->orig_node = orig_neigh_node;
|
|
||||||
neigh_node->if_incoming = if_incoming;
|
|
||||||
|
|
||||||
list_add_tail(&neigh_node->list, &orig_node->neigh_list);
|
|
||||||
return neigh_node;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void free_orig_node(void *data, void *arg)
|
|
||||||
{
|
|
||||||
struct list_head *list_pos, *list_pos_tmp;
|
|
||||||
struct neigh_node *neigh_node;
|
|
||||||
struct orig_node *orig_node = (struct orig_node *)data;
|
|
||||||
struct bat_priv *bat_priv = (struct bat_priv *)arg;
|
|
||||||
|
|
||||||
/* for all neighbors towards this originator ... */
|
|
||||||
list_for_each_safe(list_pos, list_pos_tmp, &orig_node->neigh_list) {
|
|
||||||
neigh_node = list_entry(list_pos, struct neigh_node, list);
|
|
||||||
|
|
||||||
list_del(list_pos);
|
|
||||||
kfree(neigh_node);
|
|
||||||
}
|
|
||||||
|
|
||||||
frag_list_free(&orig_node->frag_list);
|
|
||||||
hna_global_del_orig(bat_priv, orig_node, "originator timed out");
|
|
||||||
|
|
||||||
kfree(orig_node->bcast_own);
|
|
||||||
kfree(orig_node->bcast_own_sum);
|
|
||||||
kfree(orig_node);
|
|
||||||
}
|
|
||||||
|
|
||||||
void originator_free(struct bat_priv *bat_priv)
|
|
||||||
{
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
if (!bat_priv->orig_hash)
|
|
||||||
return;
|
|
||||||
|
|
||||||
cancel_delayed_work_sync(&bat_priv->orig_work);
|
|
||||||
|
|
||||||
spin_lock_irqsave(&bat_priv->orig_hash_lock, flags);
|
|
||||||
hash_delete(bat_priv->orig_hash, free_orig_node, bat_priv);
|
|
||||||
bat_priv->orig_hash = NULL;
|
|
||||||
spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* this function finds or creates an originator entry for the given
|
|
||||||
* address if it does not exits */
|
|
||||||
struct orig_node *get_orig_node(struct bat_priv *bat_priv, uint8_t *addr)
|
|
||||||
{
|
|
||||||
struct orig_node *orig_node;
|
|
||||||
struct hashtable_t *swaphash;
|
|
||||||
int size;
|
|
||||||
|
|
||||||
orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, addr));
|
|
||||||
|
|
||||||
if (orig_node)
|
|
||||||
return orig_node;
|
|
||||||
|
|
||||||
bat_dbg(DBG_BATMAN, bat_priv,
|
|
||||||
"Creating new originator: %pM\n", addr);
|
|
||||||
|
|
||||||
orig_node = kzalloc(sizeof(struct orig_node), GFP_ATOMIC);
|
|
||||||
if (!orig_node)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
INIT_LIST_HEAD(&orig_node->neigh_list);
|
|
||||||
|
|
||||||
memcpy(orig_node->orig, addr, ETH_ALEN);
|
|
||||||
orig_node->router = NULL;
|
|
||||||
orig_node->hna_buff = NULL;
|
|
||||||
orig_node->bcast_seqno_reset = jiffies - 1
|
|
||||||
- msecs_to_jiffies(RESET_PROTECTION_MS);
|
|
||||||
orig_node->batman_seqno_reset = jiffies - 1
|
|
||||||
- msecs_to_jiffies(RESET_PROTECTION_MS);
|
|
||||||
|
|
||||||
size = bat_priv->num_ifaces * sizeof(TYPE_OF_WORD) * NUM_WORDS;
|
|
||||||
|
|
||||||
orig_node->bcast_own = kzalloc(size, GFP_ATOMIC);
|
|
||||||
if (!orig_node->bcast_own)
|
|
||||||
goto free_orig_node;
|
|
||||||
|
|
||||||
size = bat_priv->num_ifaces * sizeof(uint8_t);
|
|
||||||
orig_node->bcast_own_sum = kzalloc(size, GFP_ATOMIC);
|
|
||||||
|
|
||||||
INIT_LIST_HEAD(&orig_node->frag_list);
|
|
||||||
orig_node->last_frag_packet = 0;
|
|
||||||
|
|
||||||
if (!orig_node->bcast_own_sum)
|
|
||||||
goto free_bcast_own;
|
|
||||||
|
|
||||||
if (hash_add(bat_priv->orig_hash, orig_node) < 0)
|
|
||||||
goto free_bcast_own_sum;
|
|
||||||
|
|
||||||
if (bat_priv->orig_hash->elements * 4 > bat_priv->orig_hash->size) {
|
|
||||||
swaphash = hash_resize(bat_priv->orig_hash,
|
|
||||||
bat_priv->orig_hash->size * 2);
|
|
||||||
|
|
||||||
if (!swaphash)
|
|
||||||
bat_dbg(DBG_BATMAN, bat_priv,
|
|
||||||
"Couldn't resize orig hash table\n");
|
|
||||||
else
|
|
||||||
bat_priv->orig_hash = swaphash;
|
|
||||||
}
|
|
||||||
|
|
||||||
return orig_node;
|
|
||||||
free_bcast_own_sum:
|
|
||||||
kfree(orig_node->bcast_own_sum);
|
|
||||||
free_bcast_own:
|
|
||||||
kfree(orig_node->bcast_own);
|
|
||||||
free_orig_node:
|
|
||||||
kfree(orig_node);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool purge_orig_neighbors(struct bat_priv *bat_priv,
|
|
||||||
struct orig_node *orig_node,
|
|
||||||
struct neigh_node **best_neigh_node)
|
|
||||||
{
|
|
||||||
struct list_head *list_pos, *list_pos_tmp;
|
|
||||||
struct neigh_node *neigh_node;
|
|
||||||
bool neigh_purged = false;
|
|
||||||
|
|
||||||
*best_neigh_node = NULL;
|
|
||||||
|
|
||||||
/* for all neighbors towards this originator ... */
|
|
||||||
list_for_each_safe(list_pos, list_pos_tmp, &orig_node->neigh_list) {
|
|
||||||
neigh_node = list_entry(list_pos, struct neigh_node, list);
|
|
||||||
|
|
||||||
if ((time_after(jiffies,
|
|
||||||
neigh_node->last_valid + PURGE_TIMEOUT * HZ)) ||
|
|
||||||
(neigh_node->if_incoming->if_status == IF_INACTIVE) ||
|
|
||||||
(neigh_node->if_incoming->if_status == IF_TO_BE_REMOVED)) {
|
|
||||||
|
|
||||||
if (neigh_node->if_incoming->if_status ==
|
|
||||||
IF_TO_BE_REMOVED)
|
|
||||||
bat_dbg(DBG_BATMAN, bat_priv,
|
|
||||||
"neighbor purge: originator %pM, "
|
|
||||||
"neighbor: %pM, iface: %s\n",
|
|
||||||
orig_node->orig, neigh_node->addr,
|
|
||||||
neigh_node->if_incoming->net_dev->name);
|
|
||||||
else
|
|
||||||
bat_dbg(DBG_BATMAN, bat_priv,
|
|
||||||
"neighbor timeout: originator %pM, "
|
|
||||||
"neighbor: %pM, last_valid: %lu\n",
|
|
||||||
orig_node->orig, neigh_node->addr,
|
|
||||||
(neigh_node->last_valid / HZ));
|
|
||||||
|
|
||||||
neigh_purged = true;
|
|
||||||
list_del(list_pos);
|
|
||||||
kfree(neigh_node);
|
|
||||||
} else {
|
|
||||||
if ((*best_neigh_node == NULL) ||
|
|
||||||
(neigh_node->tq_avg > (*best_neigh_node)->tq_avg))
|
|
||||||
*best_neigh_node = neigh_node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return neigh_purged;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool purge_orig_node(struct bat_priv *bat_priv,
|
|
||||||
struct orig_node *orig_node)
|
|
||||||
{
|
|
||||||
struct neigh_node *best_neigh_node;
|
|
||||||
|
|
||||||
if (time_after(jiffies,
|
|
||||||
orig_node->last_valid + 2 * PURGE_TIMEOUT * HZ)) {
|
|
||||||
|
|
||||||
bat_dbg(DBG_BATMAN, bat_priv,
|
|
||||||
"Originator timeout: originator %pM, last_valid %lu\n",
|
|
||||||
orig_node->orig, (orig_node->last_valid / HZ));
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
if (purge_orig_neighbors(bat_priv, orig_node,
|
|
||||||
&best_neigh_node)) {
|
|
||||||
update_routes(bat_priv, orig_node,
|
|
||||||
best_neigh_node,
|
|
||||||
orig_node->hna_buff,
|
|
||||||
orig_node->hna_buff_len);
|
|
||||||
/* update bonding candidates, we could have lost
|
|
||||||
* some candidates. */
|
|
||||||
update_bonding_candidates(bat_priv, orig_node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _purge_orig(struct bat_priv *bat_priv)
|
|
||||||
{
|
|
||||||
HASHIT(hashit);
|
|
||||||
struct orig_node *orig_node;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&bat_priv->orig_hash_lock, flags);
|
|
||||||
|
|
||||||
/* for all origins... */
|
|
||||||
while (hash_iterate(bat_priv->orig_hash, &hashit)) {
|
|
||||||
orig_node = hashit.bucket->data;
|
|
||||||
|
|
||||||
if (purge_orig_node(bat_priv, orig_node)) {
|
|
||||||
hash_remove_bucket(bat_priv->orig_hash, &hashit);
|
|
||||||
free_orig_node(orig_node, bat_priv);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (time_after(jiffies, (orig_node->last_frag_packet +
|
|
||||||
msecs_to_jiffies(FRAG_TIMEOUT))))
|
|
||||||
frag_list_free(&orig_node->frag_list);
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static void purge_orig(struct work_struct *work)
|
|
||||||
{
|
|
||||||
struct delayed_work *delayed_work =
|
|
||||||
container_of(work, struct delayed_work, work);
|
|
||||||
struct bat_priv *bat_priv =
|
|
||||||
container_of(delayed_work, struct bat_priv, orig_work);
|
|
||||||
|
|
||||||
_purge_orig(bat_priv);
|
|
||||||
start_purge_timer(bat_priv);
|
|
||||||
}
|
|
||||||
|
|
||||||
void purge_orig_ref(struct bat_priv *bat_priv)
|
|
||||||
{
|
|
||||||
_purge_orig(bat_priv);
|
|
||||||
}
|
|
||||||
|
|
||||||
int orig_seq_print_text(struct seq_file *seq, void *offset)
|
|
||||||
{
|
|
||||||
HASHIT(hashit);
|
|
||||||
struct net_device *net_dev = (struct net_device *)seq->private;
|
|
||||||
struct bat_priv *bat_priv = netdev_priv(net_dev);
|
|
||||||
struct orig_node *orig_node;
|
|
||||||
struct neigh_node *neigh_node;
|
|
||||||
int batman_count = 0;
|
|
||||||
int last_seen_secs;
|
|
||||||
int last_seen_msecs;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
if ((!bat_priv->primary_if) ||
|
|
||||||
(bat_priv->primary_if->if_status != IF_ACTIVE)) {
|
|
||||||
if (!bat_priv->primary_if)
|
|
||||||
return seq_printf(seq, "BATMAN mesh %s disabled - "
|
|
||||||
"please specify interfaces to enable it\n",
|
|
||||||
net_dev->name);
|
|
||||||
|
|
||||||
return seq_printf(seq, "BATMAN mesh %s "
|
|
||||||
"disabled - primary interface not active\n",
|
|
||||||
net_dev->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
seq_printf(seq, "[B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%pM (%s)]\n",
|
|
||||||
SOURCE_VERSION, REVISION_VERSION_STR,
|
|
||||||
bat_priv->primary_if->net_dev->name,
|
|
||||||
bat_priv->primary_if->net_dev->dev_addr, net_dev->name);
|
|
||||||
seq_printf(seq, " %-15s %s (%s/%i) %17s [%10s]: %20s ...\n",
|
|
||||||
"Originator", "last-seen", "#", TQ_MAX_VALUE, "Nexthop",
|
|
||||||
"outgoingIF", "Potential nexthops");
|
|
||||||
|
|
||||||
spin_lock_irqsave(&bat_priv->orig_hash_lock, flags);
|
|
||||||
|
|
||||||
while (hash_iterate(bat_priv->orig_hash, &hashit)) {
|
|
||||||
|
|
||||||
orig_node = hashit.bucket->data;
|
|
||||||
|
|
||||||
if (!orig_node->router)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (orig_node->router->tq_avg == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
last_seen_secs = jiffies_to_msecs(jiffies -
|
|
||||||
orig_node->last_valid) / 1000;
|
|
||||||
last_seen_msecs = jiffies_to_msecs(jiffies -
|
|
||||||
orig_node->last_valid) % 1000;
|
|
||||||
|
|
||||||
seq_printf(seq, "%pM %4i.%03is (%3i) %pM [%10s]:",
|
|
||||||
orig_node->orig, last_seen_secs, last_seen_msecs,
|
|
||||||
orig_node->router->tq_avg, orig_node->router->addr,
|
|
||||||
orig_node->router->if_incoming->net_dev->name);
|
|
||||||
|
|
||||||
list_for_each_entry(neigh_node, &orig_node->neigh_list, list) {
|
|
||||||
seq_printf(seq, " %pM (%3i)", neigh_node->addr,
|
|
||||||
neigh_node->tq_avg);
|
|
||||||
}
|
|
||||||
|
|
||||||
seq_printf(seq, "\n");
|
|
||||||
batman_count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
|
|
||||||
|
|
||||||
if ((batman_count == 0))
|
|
||||||
seq_printf(seq, "No batman nodes in range ...\n");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int orig_node_add_if(struct orig_node *orig_node, int max_if_num)
|
|
||||||
{
|
|
||||||
void *data_ptr;
|
|
||||||
|
|
||||||
data_ptr = kmalloc(max_if_num * sizeof(TYPE_OF_WORD) * NUM_WORDS,
|
|
||||||
GFP_ATOMIC);
|
|
||||||
if (!data_ptr) {
|
|
||||||
pr_err("Can't resize orig: out of memory\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(data_ptr, orig_node->bcast_own,
|
|
||||||
(max_if_num - 1) * sizeof(TYPE_OF_WORD) * NUM_WORDS);
|
|
||||||
kfree(orig_node->bcast_own);
|
|
||||||
orig_node->bcast_own = data_ptr;
|
|
||||||
|
|
||||||
data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC);
|
|
||||||
if (!data_ptr) {
|
|
||||||
pr_err("Can't resize orig: out of memory\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(data_ptr, orig_node->bcast_own_sum,
|
|
||||||
(max_if_num - 1) * sizeof(uint8_t));
|
|
||||||
kfree(orig_node->bcast_own_sum);
|
|
||||||
orig_node->bcast_own_sum = data_ptr;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int orig_hash_add_if(struct batman_if *batman_if, int max_if_num)
|
|
||||||
{
|
|
||||||
struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface);
|
|
||||||
struct orig_node *orig_node;
|
|
||||||
unsigned long flags;
|
|
||||||
HASHIT(hashit);
|
|
||||||
|
|
||||||
/* resize all orig nodes because orig_node->bcast_own(_sum) depend on
|
|
||||||
* if_num */
|
|
||||||
spin_lock_irqsave(&bat_priv->orig_hash_lock, flags);
|
|
||||||
|
|
||||||
while (hash_iterate(bat_priv->orig_hash, &hashit)) {
|
|
||||||
orig_node = hashit.bucket->data;
|
|
||||||
|
|
||||||
if (orig_node_add_if(orig_node, max_if_num) == -1)
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
err:
|
|
||||||
spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int orig_node_del_if(struct orig_node *orig_node,
|
|
||||||
int max_if_num, int del_if_num)
|
|
||||||
{
|
|
||||||
void *data_ptr = NULL;
|
|
||||||
int chunk_size;
|
|
||||||
|
|
||||||
/* last interface was removed */
|
|
||||||
if (max_if_num == 0)
|
|
||||||
goto free_bcast_own;
|
|
||||||
|
|
||||||
chunk_size = sizeof(TYPE_OF_WORD) * NUM_WORDS;
|
|
||||||
data_ptr = kmalloc(max_if_num * chunk_size, GFP_ATOMIC);
|
|
||||||
if (!data_ptr) {
|
|
||||||
pr_err("Can't resize orig: out of memory\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* copy first part */
|
|
||||||
memcpy(data_ptr, orig_node->bcast_own, del_if_num * chunk_size);
|
|
||||||
|
|
||||||
/* copy second part */
|
|
||||||
memcpy(data_ptr + del_if_num * chunk_size,
|
|
||||||
orig_node->bcast_own + ((del_if_num + 1) * chunk_size),
|
|
||||||
(max_if_num - del_if_num) * chunk_size);
|
|
||||||
|
|
||||||
free_bcast_own:
|
|
||||||
kfree(orig_node->bcast_own);
|
|
||||||
orig_node->bcast_own = data_ptr;
|
|
||||||
|
|
||||||
if (max_if_num == 0)
|
|
||||||
goto free_own_sum;
|
|
||||||
|
|
||||||
data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC);
|
|
||||||
if (!data_ptr) {
|
|
||||||
pr_err("Can't resize orig: out of memory\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(data_ptr, orig_node->bcast_own_sum,
|
|
||||||
del_if_num * sizeof(uint8_t));
|
|
||||||
|
|
||||||
memcpy(data_ptr + del_if_num * sizeof(uint8_t),
|
|
||||||
orig_node->bcast_own_sum + ((del_if_num + 1) * sizeof(uint8_t)),
|
|
||||||
(max_if_num - del_if_num) * sizeof(uint8_t));
|
|
||||||
|
|
||||||
free_own_sum:
|
|
||||||
kfree(orig_node->bcast_own_sum);
|
|
||||||
orig_node->bcast_own_sum = data_ptr;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int orig_hash_del_if(struct batman_if *batman_if, int max_if_num)
|
|
||||||
{
|
|
||||||
struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface);
|
|
||||||
struct batman_if *batman_if_tmp;
|
|
||||||
struct orig_node *orig_node;
|
|
||||||
unsigned long flags;
|
|
||||||
HASHIT(hashit);
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* resize all orig nodes because orig_node->bcast_own(_sum) depend on
|
|
||||||
* if_num */
|
|
||||||
spin_lock_irqsave(&bat_priv->orig_hash_lock, flags);
|
|
||||||
|
|
||||||
while (hash_iterate(bat_priv->orig_hash, &hashit)) {
|
|
||||||
orig_node = hashit.bucket->data;
|
|
||||||
|
|
||||||
ret = orig_node_del_if(orig_node, max_if_num,
|
|
||||||
batman_if->if_num);
|
|
||||||
|
|
||||||
if (ret == -1)
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* renumber remaining batman interfaces _inside_ of orig_hash_lock */
|
|
||||||
rcu_read_lock();
|
|
||||||
list_for_each_entry_rcu(batman_if_tmp, &if_list, list) {
|
|
||||||
if (batman_if_tmp->if_status == IF_NOT_IN_USE)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (batman_if == batman_if_tmp)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (batman_if->soft_iface != batman_if_tmp->soft_iface)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (batman_if_tmp->if_num > batman_if->if_num)
|
|
||||||
batman_if_tmp->if_num--;
|
|
||||||
}
|
|
||||||
rcu_read_unlock();
|
|
||||||
|
|
||||||
batman_if->if_num = -1;
|
|
||||||
spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
err:
|
|
||||||
spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
|
|
||||||
*
|
|
||||||
* Marek Lindner, Simon Wunderlich
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of version 2 of the GNU General Public
|
|
||||||
* License as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
||||||
* 02110-1301, USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _NET_BATMAN_ADV_ORIGINATOR_H_
|
|
||||||
#define _NET_BATMAN_ADV_ORIGINATOR_H_
|
|
||||||
|
|
||||||
int originator_init(struct bat_priv *bat_priv);
|
|
||||||
void originator_free(struct bat_priv *bat_priv);
|
|
||||||
void purge_orig_ref(struct bat_priv *bat_priv);
|
|
||||||
struct orig_node *get_orig_node(struct bat_priv *bat_priv, uint8_t *addr);
|
|
||||||
struct neigh_node *
|
|
||||||
create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node,
|
|
||||||
uint8_t *neigh, struct batman_if *if_incoming);
|
|
||||||
int orig_seq_print_text(struct seq_file *seq, void *offset);
|
|
||||||
int orig_hash_add_if(struct batman_if *batman_if, int max_if_num);
|
|
||||||
int orig_hash_del_if(struct batman_if *batman_if, int max_if_num);
|
|
||||||
|
|
||||||
#endif /* _NET_BATMAN_ADV_ORIGINATOR_H_ */
|
|
@ -1,134 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
|
|
||||||
*
|
|
||||||
* Marek Lindner, Simon Wunderlich
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of version 2 of the GNU General Public
|
|
||||||
* License as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
||||||
* 02110-1301, USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _NET_BATMAN_ADV_PACKET_H_
|
|
||||||
#define _NET_BATMAN_ADV_PACKET_H_
|
|
||||||
|
|
||||||
#define ETH_P_BATMAN 0x4305 /* unofficial/not registered Ethertype */
|
|
||||||
|
|
||||||
#define BAT_PACKET 0x01
|
|
||||||
#define BAT_ICMP 0x02
|
|
||||||
#define BAT_UNICAST 0x03
|
|
||||||
#define BAT_BCAST 0x04
|
|
||||||
#define BAT_VIS 0x05
|
|
||||||
#define BAT_UNICAST_FRAG 0x06
|
|
||||||
|
|
||||||
/* this file is included by batctl which needs these defines */
|
|
||||||
#define COMPAT_VERSION 13
|
|
||||||
#define DIRECTLINK 0x40
|
|
||||||
#define VIS_SERVER 0x20
|
|
||||||
#define PRIMARIES_FIRST_HOP 0x10
|
|
||||||
|
|
||||||
/* ICMP message types */
|
|
||||||
#define ECHO_REPLY 0
|
|
||||||
#define DESTINATION_UNREACHABLE 3
|
|
||||||
#define ECHO_REQUEST 8
|
|
||||||
#define TTL_EXCEEDED 11
|
|
||||||
#define PARAMETER_PROBLEM 12
|
|
||||||
|
|
||||||
/* vis defines */
|
|
||||||
#define VIS_TYPE_SERVER_SYNC 0
|
|
||||||
#define VIS_TYPE_CLIENT_UPDATE 1
|
|
||||||
|
|
||||||
/* fragmentation defines */
|
|
||||||
#define UNI_FRAG_HEAD 0x01
|
|
||||||
|
|
||||||
struct batman_packet {
|
|
||||||
uint8_t packet_type;
|
|
||||||
uint8_t version; /* batman version field */
|
|
||||||
uint8_t flags; /* 0x40: DIRECTLINK flag, 0x20 VIS_SERVER flag... */
|
|
||||||
uint8_t tq;
|
|
||||||
uint32_t seqno;
|
|
||||||
uint8_t orig[6];
|
|
||||||
uint8_t prev_sender[6];
|
|
||||||
uint8_t ttl;
|
|
||||||
uint8_t num_hna;
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
#define BAT_PACKET_LEN sizeof(struct batman_packet)
|
|
||||||
|
|
||||||
struct icmp_packet {
|
|
||||||
uint8_t packet_type;
|
|
||||||
uint8_t version; /* batman version field */
|
|
||||||
uint8_t msg_type; /* see ICMP message types above */
|
|
||||||
uint8_t ttl;
|
|
||||||
uint8_t dst[6];
|
|
||||||
uint8_t orig[6];
|
|
||||||
uint16_t seqno;
|
|
||||||
uint8_t uid;
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
#define BAT_RR_LEN 16
|
|
||||||
|
|
||||||
/* icmp_packet_rr must start with all fields from imcp_packet
|
|
||||||
* as this is assumed by code that handles ICMP packets */
|
|
||||||
struct icmp_packet_rr {
|
|
||||||
uint8_t packet_type;
|
|
||||||
uint8_t version; /* batman version field */
|
|
||||||
uint8_t msg_type; /* see ICMP message types above */
|
|
||||||
uint8_t ttl;
|
|
||||||
uint8_t dst[6];
|
|
||||||
uint8_t orig[6];
|
|
||||||
uint16_t seqno;
|
|
||||||
uint8_t uid;
|
|
||||||
uint8_t rr_cur;
|
|
||||||
uint8_t rr[BAT_RR_LEN][ETH_ALEN];
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
struct unicast_packet {
|
|
||||||
uint8_t packet_type;
|
|
||||||
uint8_t version; /* batman version field */
|
|
||||||
uint8_t dest[6];
|
|
||||||
uint8_t ttl;
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
struct unicast_frag_packet {
|
|
||||||
uint8_t packet_type;
|
|
||||||
uint8_t version; /* batman version field */
|
|
||||||
uint8_t dest[6];
|
|
||||||
uint8_t ttl;
|
|
||||||
uint8_t flags;
|
|
||||||
uint8_t orig[6];
|
|
||||||
uint16_t seqno;
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
struct bcast_packet {
|
|
||||||
uint8_t packet_type;
|
|
||||||
uint8_t version; /* batman version field */
|
|
||||||
uint8_t orig[6];
|
|
||||||
uint8_t ttl;
|
|
||||||
uint32_t seqno;
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
struct vis_packet {
|
|
||||||
uint8_t packet_type;
|
|
||||||
uint8_t version; /* batman version field */
|
|
||||||
uint8_t vis_type; /* which type of vis-participant sent this? */
|
|
||||||
uint8_t entries; /* number of entries behind this struct */
|
|
||||||
uint32_t seqno; /* sequence number */
|
|
||||||
uint8_t ttl; /* TTL */
|
|
||||||
uint8_t vis_orig[6]; /* originator that informs about its
|
|
||||||
* neighbors */
|
|
||||||
uint8_t target_orig[6]; /* who should receive this packet */
|
|
||||||
uint8_t sender_orig[6]; /* who sent or rebroadcasted this packet */
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
#endif /* _NET_BATMAN_ADV_PACKET_H_ */
|
|
@ -1,52 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
|
|
||||||
*
|
|
||||||
* Marek Lindner
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of version 2 of the GNU General Public
|
|
||||||
* License as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
||||||
* 02110-1301, USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "main.h"
|
|
||||||
#include "ring_buffer.h"
|
|
||||||
|
|
||||||
void ring_buffer_set(uint8_t lq_recv[], uint8_t *lq_index, uint8_t value)
|
|
||||||
{
|
|
||||||
lq_recv[*lq_index] = value;
|
|
||||||
*lq_index = (*lq_index + 1) % TQ_GLOBAL_WINDOW_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t ring_buffer_avg(uint8_t lq_recv[])
|
|
||||||
{
|
|
||||||
uint8_t *ptr;
|
|
||||||
uint16_t count = 0, i = 0, sum = 0;
|
|
||||||
|
|
||||||
ptr = lq_recv;
|
|
||||||
|
|
||||||
while (i < TQ_GLOBAL_WINDOW_SIZE) {
|
|
||||||
if (*ptr != 0) {
|
|
||||||
count++;
|
|
||||||
sum += *ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
i++;
|
|
||||||
ptr++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return (uint8_t)(sum / count);
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
|
|
||||||
*
|
|
||||||
* Marek Lindner
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of version 2 of the GNU General Public
|
|
||||||
* License as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
||||||
* 02110-1301, USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _NET_BATMAN_ADV_RING_BUFFER_H_
|
|
||||||
#define _NET_BATMAN_ADV_RING_BUFFER_H_
|
|
||||||
|
|
||||||
void ring_buffer_set(uint8_t lq_recv[], uint8_t *lq_index, uint8_t value);
|
|
||||||
uint8_t ring_buffer_avg(uint8_t lq_recv[]);
|
|
||||||
|
|
||||||
#endif /* _NET_BATMAN_ADV_RING_BUFFER_H_ */
|
|
File diff suppressed because it is too large
Load Diff
@ -1,46 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
|
|
||||||
*
|
|
||||||
* Marek Lindner, Simon Wunderlich
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of version 2 of the GNU General Public
|
|
||||||
* License as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
||||||
* 02110-1301, USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _NET_BATMAN_ADV_ROUTING_H_
|
|
||||||
#define _NET_BATMAN_ADV_ROUTING_H_
|
|
||||||
|
|
||||||
#include "types.h"
|
|
||||||
|
|
||||||
void slide_own_bcast_window(struct batman_if *batman_if);
|
|
||||||
void receive_bat_packet(struct ethhdr *ethhdr,
|
|
||||||
struct batman_packet *batman_packet,
|
|
||||||
unsigned char *hna_buff, int hna_buff_len,
|
|
||||||
struct batman_if *if_incoming);
|
|
||||||
void update_routes(struct bat_priv *bat_priv, struct orig_node *orig_node,
|
|
||||||
struct neigh_node *neigh_node, unsigned char *hna_buff,
|
|
||||||
int hna_buff_len);
|
|
||||||
int recv_icmp_packet(struct sk_buff *skb, struct batman_if *recv_if);
|
|
||||||
int recv_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if);
|
|
||||||
int recv_ucast_frag_packet(struct sk_buff *skb, struct batman_if *recv_if);
|
|
||||||
int recv_bcast_packet(struct sk_buff *skb, struct batman_if *recv_if);
|
|
||||||
int recv_vis_packet(struct sk_buff *skb, struct batman_if *recv_if);
|
|
||||||
int recv_bat_packet(struct sk_buff *skb, struct batman_if *recv_if);
|
|
||||||
struct neigh_node *find_router(struct bat_priv *bat_priv,
|
|
||||||
struct orig_node *orig_node, struct batman_if *recv_if);
|
|
||||||
void update_bonding_candidates(struct bat_priv *bat_priv,
|
|
||||||
struct orig_node *orig_node);
|
|
||||||
|
|
||||||
#endif /* _NET_BATMAN_ADV_ROUTING_H_ */
|
|
@ -1,580 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
|
|
||||||
*
|
|
||||||
* Marek Lindner, Simon Wunderlich
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of version 2 of the GNU General Public
|
|
||||||
* License as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
||||||
* 02110-1301, USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "main.h"
|
|
||||||
#include "send.h"
|
|
||||||
#include "routing.h"
|
|
||||||
#include "translation-table.h"
|
|
||||||
#include "soft-interface.h"
|
|
||||||
#include "hard-interface.h"
|
|
||||||
#include "types.h"
|
|
||||||
#include "vis.h"
|
|
||||||
#include "aggregation.h"
|
|
||||||
|
|
||||||
|
|
||||||
static void send_outstanding_bcast_packet(struct work_struct *work);
|
|
||||||
|
|
||||||
/* apply hop penalty for a normal link */
|
|
||||||
static uint8_t hop_penalty(const uint8_t tq)
|
|
||||||
{
|
|
||||||
return (tq * (TQ_MAX_VALUE - TQ_HOP_PENALTY)) / (TQ_MAX_VALUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* when do we schedule our own packet to be sent */
|
|
||||||
static unsigned long own_send_time(struct bat_priv *bat_priv)
|
|
||||||
{
|
|
||||||
return jiffies + msecs_to_jiffies(
|
|
||||||
atomic_read(&bat_priv->orig_interval) -
|
|
||||||
JITTER + (random32() % 2*JITTER));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* when do we schedule a forwarded packet to be sent */
|
|
||||||
static unsigned long forward_send_time(struct bat_priv *bat_priv)
|
|
||||||
{
|
|
||||||
return jiffies + msecs_to_jiffies(random32() % (JITTER/2));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* send out an already prepared packet to the given address via the
|
|
||||||
* specified batman interface */
|
|
||||||
int send_skb_packet(struct sk_buff *skb,
|
|
||||||
struct batman_if *batman_if,
|
|
||||||
uint8_t *dst_addr)
|
|
||||||
{
|
|
||||||
struct ethhdr *ethhdr;
|
|
||||||
|
|
||||||
if (batman_if->if_status != IF_ACTIVE)
|
|
||||||
goto send_skb_err;
|
|
||||||
|
|
||||||
if (unlikely(!batman_if->net_dev))
|
|
||||||
goto send_skb_err;
|
|
||||||
|
|
||||||
if (!(batman_if->net_dev->flags & IFF_UP)) {
|
|
||||||
pr_warning("Interface %s is not up - can't send packet via "
|
|
||||||
"that interface!\n", batman_if->net_dev->name);
|
|
||||||
goto send_skb_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* push to the ethernet header. */
|
|
||||||
if (my_skb_head_push(skb, sizeof(struct ethhdr)) < 0)
|
|
||||||
goto send_skb_err;
|
|
||||||
|
|
||||||
skb_reset_mac_header(skb);
|
|
||||||
|
|
||||||
ethhdr = (struct ethhdr *) skb_mac_header(skb);
|
|
||||||
memcpy(ethhdr->h_source, batman_if->net_dev->dev_addr, ETH_ALEN);
|
|
||||||
memcpy(ethhdr->h_dest, dst_addr, ETH_ALEN);
|
|
||||||
ethhdr->h_proto = __constant_htons(ETH_P_BATMAN);
|
|
||||||
|
|
||||||
skb_set_network_header(skb, ETH_HLEN);
|
|
||||||
skb->priority = TC_PRIO_CONTROL;
|
|
||||||
skb->protocol = __constant_htons(ETH_P_BATMAN);
|
|
||||||
|
|
||||||
skb->dev = batman_if->net_dev;
|
|
||||||
|
|
||||||
/* dev_queue_xmit() returns a negative result on error. However on
|
|
||||||
* congestion and traffic shaping, it drops and returns NET_XMIT_DROP
|
|
||||||
* (which is > 0). This will not be treated as an error. */
|
|
||||||
|
|
||||||
return dev_queue_xmit(skb);
|
|
||||||
send_skb_err:
|
|
||||||
kfree_skb(skb);
|
|
||||||
return NET_XMIT_DROP;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Send a packet to a given interface */
|
|
||||||
static void send_packet_to_if(struct forw_packet *forw_packet,
|
|
||||||
struct batman_if *batman_if)
|
|
||||||
{
|
|
||||||
struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface);
|
|
||||||
char *fwd_str;
|
|
||||||
uint8_t packet_num;
|
|
||||||
int16_t buff_pos;
|
|
||||||
struct batman_packet *batman_packet;
|
|
||||||
struct sk_buff *skb;
|
|
||||||
|
|
||||||
if (batman_if->if_status != IF_ACTIVE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
packet_num = 0;
|
|
||||||
buff_pos = 0;
|
|
||||||
batman_packet = (struct batman_packet *)forw_packet->skb->data;
|
|
||||||
|
|
||||||
/* adjust all flags and log packets */
|
|
||||||
while (aggregated_packet(buff_pos,
|
|
||||||
forw_packet->packet_len,
|
|
||||||
batman_packet->num_hna)) {
|
|
||||||
|
|
||||||
/* we might have aggregated direct link packets with an
|
|
||||||
* ordinary base packet */
|
|
||||||
if ((forw_packet->direct_link_flags & (1 << packet_num)) &&
|
|
||||||
(forw_packet->if_incoming == batman_if))
|
|
||||||
batman_packet->flags |= DIRECTLINK;
|
|
||||||
else
|
|
||||||
batman_packet->flags &= ~DIRECTLINK;
|
|
||||||
|
|
||||||
fwd_str = (packet_num > 0 ? "Forwarding" : (forw_packet->own ?
|
|
||||||
"Sending own" :
|
|
||||||
"Forwarding"));
|
|
||||||
bat_dbg(DBG_BATMAN, bat_priv,
|
|
||||||
"%s %spacket (originator %pM, seqno %d, TQ %d, TTL %d,"
|
|
||||||
" IDF %s) on interface %s [%pM]\n",
|
|
||||||
fwd_str, (packet_num > 0 ? "aggregated " : ""),
|
|
||||||
batman_packet->orig, ntohl(batman_packet->seqno),
|
|
||||||
batman_packet->tq, batman_packet->ttl,
|
|
||||||
(batman_packet->flags & DIRECTLINK ?
|
|
||||||
"on" : "off"),
|
|
||||||
batman_if->net_dev->name, batman_if->net_dev->dev_addr);
|
|
||||||
|
|
||||||
buff_pos += sizeof(struct batman_packet) +
|
|
||||||
(batman_packet->num_hna * ETH_ALEN);
|
|
||||||
packet_num++;
|
|
||||||
batman_packet = (struct batman_packet *)
|
|
||||||
(forw_packet->skb->data + buff_pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* create clone because function is called more than once */
|
|
||||||
skb = skb_clone(forw_packet->skb, GFP_ATOMIC);
|
|
||||||
if (skb)
|
|
||||||
send_skb_packet(skb, batman_if, broadcast_addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* send a batman packet */
|
|
||||||
static void send_packet(struct forw_packet *forw_packet)
|
|
||||||
{
|
|
||||||
struct batman_if *batman_if;
|
|
||||||
struct net_device *soft_iface;
|
|
||||||
struct bat_priv *bat_priv;
|
|
||||||
struct batman_packet *batman_packet =
|
|
||||||
(struct batman_packet *)(forw_packet->skb->data);
|
|
||||||
unsigned char directlink = (batman_packet->flags & DIRECTLINK ? 1 : 0);
|
|
||||||
|
|
||||||
if (!forw_packet->if_incoming) {
|
|
||||||
pr_err("Error - can't forward packet: incoming iface not "
|
|
||||||
"specified\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
soft_iface = forw_packet->if_incoming->soft_iface;
|
|
||||||
bat_priv = netdev_priv(soft_iface);
|
|
||||||
|
|
||||||
if (forw_packet->if_incoming->if_status != IF_ACTIVE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* multihomed peer assumed */
|
|
||||||
/* non-primary OGMs are only broadcasted on their interface */
|
|
||||||
if ((directlink && (batman_packet->ttl == 1)) ||
|
|
||||||
(forw_packet->own && (forw_packet->if_incoming->if_num > 0))) {
|
|
||||||
|
|
||||||
/* FIXME: what about aggregated packets ? */
|
|
||||||
bat_dbg(DBG_BATMAN, bat_priv,
|
|
||||||
"%s packet (originator %pM, seqno %d, TTL %d) "
|
|
||||||
"on interface %s [%pM]\n",
|
|
||||||
(forw_packet->own ? "Sending own" : "Forwarding"),
|
|
||||||
batman_packet->orig, ntohl(batman_packet->seqno),
|
|
||||||
batman_packet->ttl,
|
|
||||||
forw_packet->if_incoming->net_dev->name,
|
|
||||||
forw_packet->if_incoming->net_dev->dev_addr);
|
|
||||||
|
|
||||||
/* skb is only used once and than forw_packet is free'd */
|
|
||||||
send_skb_packet(forw_packet->skb, forw_packet->if_incoming,
|
|
||||||
broadcast_addr);
|
|
||||||
forw_packet->skb = NULL;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* broadcast on every interface */
|
|
||||||
rcu_read_lock();
|
|
||||||
list_for_each_entry_rcu(batman_if, &if_list, list) {
|
|
||||||
if (batman_if->soft_iface != soft_iface)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
send_packet_to_if(forw_packet, batman_if);
|
|
||||||
}
|
|
||||||
rcu_read_unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void rebuild_batman_packet(struct bat_priv *bat_priv,
|
|
||||||
struct batman_if *batman_if)
|
|
||||||
{
|
|
||||||
int new_len;
|
|
||||||
unsigned char *new_buff;
|
|
||||||
struct batman_packet *batman_packet;
|
|
||||||
|
|
||||||
new_len = sizeof(struct batman_packet) +
|
|
||||||
(bat_priv->num_local_hna * ETH_ALEN);
|
|
||||||
new_buff = kmalloc(new_len, GFP_ATOMIC);
|
|
||||||
|
|
||||||
/* keep old buffer if kmalloc should fail */
|
|
||||||
if (new_buff) {
|
|
||||||
memcpy(new_buff, batman_if->packet_buff,
|
|
||||||
sizeof(struct batman_packet));
|
|
||||||
batman_packet = (struct batman_packet *)new_buff;
|
|
||||||
|
|
||||||
batman_packet->num_hna = hna_local_fill_buffer(bat_priv,
|
|
||||||
new_buff + sizeof(struct batman_packet),
|
|
||||||
new_len - sizeof(struct batman_packet));
|
|
||||||
|
|
||||||
kfree(batman_if->packet_buff);
|
|
||||||
batman_if->packet_buff = new_buff;
|
|
||||||
batman_if->packet_len = new_len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void schedule_own_packet(struct batman_if *batman_if)
|
|
||||||
{
|
|
||||||
struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface);
|
|
||||||
unsigned long send_time;
|
|
||||||
struct batman_packet *batman_packet;
|
|
||||||
int vis_server;
|
|
||||||
|
|
||||||
if ((batman_if->if_status == IF_NOT_IN_USE) ||
|
|
||||||
(batman_if->if_status == IF_TO_BE_REMOVED))
|
|
||||||
return;
|
|
||||||
|
|
||||||
vis_server = atomic_read(&bat_priv->vis_mode);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* the interface gets activated here to avoid race conditions between
|
|
||||||
* the moment of activating the interface in
|
|
||||||
* hardif_activate_interface() where the originator mac is set and
|
|
||||||
* outdated packets (especially uninitialized mac addresses) in the
|
|
||||||
* packet queue
|
|
||||||
*/
|
|
||||||
if (batman_if->if_status == IF_TO_BE_ACTIVATED)
|
|
||||||
batman_if->if_status = IF_ACTIVE;
|
|
||||||
|
|
||||||
/* if local hna has changed and interface is a primary interface */
|
|
||||||
if ((atomic_read(&bat_priv->hna_local_changed)) &&
|
|
||||||
(batman_if == bat_priv->primary_if))
|
|
||||||
rebuild_batman_packet(bat_priv, batman_if);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* NOTE: packet_buff might just have been re-allocated in
|
|
||||||
* rebuild_batman_packet()
|
|
||||||
*/
|
|
||||||
batman_packet = (struct batman_packet *)batman_if->packet_buff;
|
|
||||||
|
|
||||||
/* change sequence number to network order */
|
|
||||||
batman_packet->seqno =
|
|
||||||
htonl((uint32_t)atomic_read(&batman_if->seqno));
|
|
||||||
|
|
||||||
if (vis_server == VIS_TYPE_SERVER_SYNC)
|
|
||||||
batman_packet->flags |= VIS_SERVER;
|
|
||||||
else
|
|
||||||
batman_packet->flags &= ~VIS_SERVER;
|
|
||||||
|
|
||||||
atomic_inc(&batman_if->seqno);
|
|
||||||
|
|
||||||
slide_own_bcast_window(batman_if);
|
|
||||||
send_time = own_send_time(bat_priv);
|
|
||||||
add_bat_packet_to_list(bat_priv,
|
|
||||||
batman_if->packet_buff,
|
|
||||||
batman_if->packet_len,
|
|
||||||
batman_if, 1, send_time);
|
|
||||||
}
|
|
||||||
|
|
||||||
void schedule_forward_packet(struct orig_node *orig_node,
|
|
||||||
struct ethhdr *ethhdr,
|
|
||||||
struct batman_packet *batman_packet,
|
|
||||||
uint8_t directlink, int hna_buff_len,
|
|
||||||
struct batman_if *if_incoming)
|
|
||||||
{
|
|
||||||
struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
|
|
||||||
unsigned char in_tq, in_ttl, tq_avg = 0;
|
|
||||||
unsigned long send_time;
|
|
||||||
|
|
||||||
if (batman_packet->ttl <= 1) {
|
|
||||||
bat_dbg(DBG_BATMAN, bat_priv, "ttl exceeded\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
in_tq = batman_packet->tq;
|
|
||||||
in_ttl = batman_packet->ttl;
|
|
||||||
|
|
||||||
batman_packet->ttl--;
|
|
||||||
memcpy(batman_packet->prev_sender, ethhdr->h_source, ETH_ALEN);
|
|
||||||
|
|
||||||
/* rebroadcast tq of our best ranking neighbor to ensure the rebroadcast
|
|
||||||
* of our best tq value */
|
|
||||||
if ((orig_node->router) && (orig_node->router->tq_avg != 0)) {
|
|
||||||
|
|
||||||
/* rebroadcast ogm of best ranking neighbor as is */
|
|
||||||
if (!compare_orig(orig_node->router->addr, ethhdr->h_source)) {
|
|
||||||
batman_packet->tq = orig_node->router->tq_avg;
|
|
||||||
|
|
||||||
if (orig_node->router->last_ttl)
|
|
||||||
batman_packet->ttl = orig_node->router->last_ttl
|
|
||||||
- 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
tq_avg = orig_node->router->tq_avg;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* apply hop penalty */
|
|
||||||
batman_packet->tq = hop_penalty(batman_packet->tq);
|
|
||||||
|
|
||||||
bat_dbg(DBG_BATMAN, bat_priv,
|
|
||||||
"Forwarding packet: tq_orig: %i, tq_avg: %i, "
|
|
||||||
"tq_forw: %i, ttl_orig: %i, ttl_forw: %i\n",
|
|
||||||
in_tq, tq_avg, batman_packet->tq, in_ttl - 1,
|
|
||||||
batman_packet->ttl);
|
|
||||||
|
|
||||||
batman_packet->seqno = htonl(batman_packet->seqno);
|
|
||||||
|
|
||||||
/* switch of primaries first hop flag when forwarding */
|
|
||||||
batman_packet->flags &= ~PRIMARIES_FIRST_HOP;
|
|
||||||
if (directlink)
|
|
||||||
batman_packet->flags |= DIRECTLINK;
|
|
||||||
else
|
|
||||||
batman_packet->flags &= ~DIRECTLINK;
|
|
||||||
|
|
||||||
send_time = forward_send_time(bat_priv);
|
|
||||||
add_bat_packet_to_list(bat_priv,
|
|
||||||
(unsigned char *)batman_packet,
|
|
||||||
sizeof(struct batman_packet) + hna_buff_len,
|
|
||||||
if_incoming, 0, send_time);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void forw_packet_free(struct forw_packet *forw_packet)
|
|
||||||
{
|
|
||||||
if (forw_packet->skb)
|
|
||||||
kfree_skb(forw_packet->skb);
|
|
||||||
kfree(forw_packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _add_bcast_packet_to_list(struct bat_priv *bat_priv,
|
|
||||||
struct forw_packet *forw_packet,
|
|
||||||
unsigned long send_time)
|
|
||||||
{
|
|
||||||
unsigned long flags;
|
|
||||||
INIT_HLIST_NODE(&forw_packet->list);
|
|
||||||
|
|
||||||
/* add new packet to packet list */
|
|
||||||
spin_lock_irqsave(&bat_priv->forw_bcast_list_lock, flags);
|
|
||||||
hlist_add_head(&forw_packet->list, &bat_priv->forw_bcast_list);
|
|
||||||
spin_unlock_irqrestore(&bat_priv->forw_bcast_list_lock, flags);
|
|
||||||
|
|
||||||
/* start timer for this packet */
|
|
||||||
INIT_DELAYED_WORK(&forw_packet->delayed_work,
|
|
||||||
send_outstanding_bcast_packet);
|
|
||||||
queue_delayed_work(bat_event_workqueue, &forw_packet->delayed_work,
|
|
||||||
send_time);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0)
|
|
||||||
/* add a broadcast packet to the queue and setup timers. broadcast packets
|
|
||||||
* are sent multiple times to increase probability for beeing received.
|
|
||||||
*
|
|
||||||
* This function returns NETDEV_TX_OK on success and NETDEV_TX_BUSY on
|
|
||||||
* errors.
|
|
||||||
*
|
|
||||||
* The skb is not consumed, so the caller should make sure that the
|
|
||||||
* skb is freed. */
|
|
||||||
int add_bcast_packet_to_list(struct bat_priv *bat_priv, struct sk_buff *skb)
|
|
||||||
{
|
|
||||||
struct forw_packet *forw_packet;
|
|
||||||
struct bcast_packet *bcast_packet;
|
|
||||||
|
|
||||||
if (!atomic_dec_not_zero(&bat_priv->bcast_queue_left)) {
|
|
||||||
bat_dbg(DBG_BATMAN, bat_priv, "bcast packet queue full\n");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!bat_priv->primary_if)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
forw_packet = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC);
|
|
||||||
|
|
||||||
if (!forw_packet)
|
|
||||||
goto out_and_inc;
|
|
||||||
|
|
||||||
skb = skb_copy(skb, GFP_ATOMIC);
|
|
||||||
if (!skb)
|
|
||||||
goto packet_free;
|
|
||||||
|
|
||||||
/* as we have a copy now, it is safe to decrease the TTL */
|
|
||||||
bcast_packet = (struct bcast_packet *)skb->data;
|
|
||||||
bcast_packet->ttl--;
|
|
||||||
|
|
||||||
skb_reset_mac_header(skb);
|
|
||||||
|
|
||||||
forw_packet->skb = skb;
|
|
||||||
forw_packet->if_incoming = bat_priv->primary_if;
|
|
||||||
|
|
||||||
/* how often did we send the bcast packet ? */
|
|
||||||
forw_packet->num_packets = 0;
|
|
||||||
|
|
||||||
_add_bcast_packet_to_list(bat_priv, forw_packet, 1);
|
|
||||||
return NETDEV_TX_OK;
|
|
||||||
|
|
||||||
packet_free:
|
|
||||||
kfree(forw_packet);
|
|
||||||
out_and_inc:
|
|
||||||
atomic_inc(&bat_priv->bcast_queue_left);
|
|
||||||
out:
|
|
||||||
return NETDEV_TX_BUSY;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void send_outstanding_bcast_packet(struct work_struct *work)
|
|
||||||
{
|
|
||||||
struct batman_if *batman_if;
|
|
||||||
struct delayed_work *delayed_work =
|
|
||||||
container_of(work, struct delayed_work, work);
|
|
||||||
struct forw_packet *forw_packet =
|
|
||||||
container_of(delayed_work, struct forw_packet, delayed_work);
|
|
||||||
unsigned long flags;
|
|
||||||
struct sk_buff *skb1;
|
|
||||||
struct net_device *soft_iface = forw_packet->if_incoming->soft_iface;
|
|
||||||
struct bat_priv *bat_priv = netdev_priv(soft_iface);
|
|
||||||
|
|
||||||
spin_lock_irqsave(&bat_priv->forw_bcast_list_lock, flags);
|
|
||||||
hlist_del(&forw_packet->list);
|
|
||||||
spin_unlock_irqrestore(&bat_priv->forw_bcast_list_lock, flags);
|
|
||||||
|
|
||||||
if (atomic_read(&bat_priv->mesh_state) == MESH_DEACTIVATING)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
/* rebroadcast packet */
|
|
||||||
rcu_read_lock();
|
|
||||||
list_for_each_entry_rcu(batman_if, &if_list, list) {
|
|
||||||
if (batman_if->soft_iface != soft_iface)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* send a copy of the saved skb */
|
|
||||||
skb1 = skb_clone(forw_packet->skb, GFP_ATOMIC);
|
|
||||||
if (skb1)
|
|
||||||
send_skb_packet(skb1, batman_if, broadcast_addr);
|
|
||||||
}
|
|
||||||
rcu_read_unlock();
|
|
||||||
|
|
||||||
forw_packet->num_packets++;
|
|
||||||
|
|
||||||
/* if we still have some more bcasts to send */
|
|
||||||
if (forw_packet->num_packets < 3) {
|
|
||||||
_add_bcast_packet_to_list(bat_priv, forw_packet,
|
|
||||||
((5 * HZ) / 1000));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
forw_packet_free(forw_packet);
|
|
||||||
atomic_inc(&bat_priv->bcast_queue_left);
|
|
||||||
}
|
|
||||||
|
|
||||||
void send_outstanding_bat_packet(struct work_struct *work)
|
|
||||||
{
|
|
||||||
struct delayed_work *delayed_work =
|
|
||||||
container_of(work, struct delayed_work, work);
|
|
||||||
struct forw_packet *forw_packet =
|
|
||||||
container_of(delayed_work, struct forw_packet, delayed_work);
|
|
||||||
unsigned long flags;
|
|
||||||
struct bat_priv *bat_priv;
|
|
||||||
|
|
||||||
bat_priv = netdev_priv(forw_packet->if_incoming->soft_iface);
|
|
||||||
spin_lock_irqsave(&bat_priv->forw_bat_list_lock, flags);
|
|
||||||
hlist_del(&forw_packet->list);
|
|
||||||
spin_unlock_irqrestore(&bat_priv->forw_bat_list_lock, flags);
|
|
||||||
|
|
||||||
if (atomic_read(&bat_priv->mesh_state) == MESH_DEACTIVATING)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
send_packet(forw_packet);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* we have to have at least one packet in the queue
|
|
||||||
* to determine the queues wake up time unless we are
|
|
||||||
* shutting down
|
|
||||||
*/
|
|
||||||
if (forw_packet->own)
|
|
||||||
schedule_own_packet(forw_packet->if_incoming);
|
|
||||||
|
|
||||||
out:
|
|
||||||
/* don't count own packet */
|
|
||||||
if (!forw_packet->own)
|
|
||||||
atomic_inc(&bat_priv->batman_queue_left);
|
|
||||||
|
|
||||||
forw_packet_free(forw_packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
void purge_outstanding_packets(struct bat_priv *bat_priv,
|
|
||||||
struct batman_if *batman_if)
|
|
||||||
{
|
|
||||||
struct forw_packet *forw_packet;
|
|
||||||
struct hlist_node *tmp_node, *safe_tmp_node;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
if (batman_if)
|
|
||||||
bat_dbg(DBG_BATMAN, bat_priv,
|
|
||||||
"purge_outstanding_packets(): %s\n",
|
|
||||||
batman_if->net_dev->name);
|
|
||||||
else
|
|
||||||
bat_dbg(DBG_BATMAN, bat_priv,
|
|
||||||
"purge_outstanding_packets()\n");
|
|
||||||
|
|
||||||
/* free bcast list */
|
|
||||||
spin_lock_irqsave(&bat_priv->forw_bcast_list_lock, flags);
|
|
||||||
hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node,
|
|
||||||
&bat_priv->forw_bcast_list, list) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* if purge_outstanding_packets() was called with an argmument
|
|
||||||
* we delete only packets belonging to the given interface
|
|
||||||
*/
|
|
||||||
if ((batman_if) &&
|
|
||||||
(forw_packet->if_incoming != batman_if))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&bat_priv->forw_bcast_list_lock, flags);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* send_outstanding_bcast_packet() will lock the list to
|
|
||||||
* delete the item from the list
|
|
||||||
*/
|
|
||||||
cancel_delayed_work_sync(&forw_packet->delayed_work);
|
|
||||||
spin_lock_irqsave(&bat_priv->forw_bcast_list_lock, flags);
|
|
||||||
}
|
|
||||||
spin_unlock_irqrestore(&bat_priv->forw_bcast_list_lock, flags);
|
|
||||||
|
|
||||||
/* free batman packet list */
|
|
||||||
spin_lock_irqsave(&bat_priv->forw_bat_list_lock, flags);
|
|
||||||
hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node,
|
|
||||||
&bat_priv->forw_bat_list, list) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* if purge_outstanding_packets() was called with an argmument
|
|
||||||
* we delete only packets belonging to the given interface
|
|
||||||
*/
|
|
||||||
if ((batman_if) &&
|
|
||||||
(forw_packet->if_incoming != batman_if))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&bat_priv->forw_bat_list_lock, flags);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* send_outstanding_bat_packet() will lock the list to
|
|
||||||
* delete the item from the list
|
|
||||||
*/
|
|
||||||
cancel_delayed_work_sync(&forw_packet->delayed_work);
|
|
||||||
spin_lock_irqsave(&bat_priv->forw_bat_list_lock, flags);
|
|
||||||
}
|
|
||||||
spin_unlock_irqrestore(&bat_priv->forw_bat_list_lock, flags);
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
|
|
||||||
*
|
|
||||||
* Marek Lindner, Simon Wunderlich
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of version 2 of the GNU General Public
|
|
||||||
* License as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
||||||
* 02110-1301, USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _NET_BATMAN_ADV_SEND_H_
|
|
||||||
#define _NET_BATMAN_ADV_SEND_H_
|
|
||||||
|
|
||||||
#include "types.h"
|
|
||||||
|
|
||||||
int send_skb_packet(struct sk_buff *skb,
|
|
||||||
struct batman_if *batman_if,
|
|
||||||
uint8_t *dst_addr);
|
|
||||||
void schedule_own_packet(struct batman_if *batman_if);
|
|
||||||
void schedule_forward_packet(struct orig_node *orig_node,
|
|
||||||
struct ethhdr *ethhdr,
|
|
||||||
struct batman_packet *batman_packet,
|
|
||||||
uint8_t directlink, int hna_buff_len,
|
|
||||||
struct batman_if *if_outgoing);
|
|
||||||
int add_bcast_packet_to_list(struct bat_priv *bat_priv, struct sk_buff *skb);
|
|
||||||
void send_outstanding_bat_packet(struct work_struct *work);
|
|
||||||
void purge_outstanding_packets(struct bat_priv *bat_priv,
|
|
||||||
struct batman_if *batman_if);
|
|
||||||
|
|
||||||
#endif /* _NET_BATMAN_ADV_SEND_H_ */
|
|
@ -1,398 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
|
|
||||||
*
|
|
||||||
* Marek Lindner, Simon Wunderlich
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of version 2 of the GNU General Public
|
|
||||||
* License as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
||||||
* 02110-1301, USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "main.h"
|
|
||||||
#include "soft-interface.h"
|
|
||||||
#include "hard-interface.h"
|
|
||||||
#include "routing.h"
|
|
||||||
#include "send.h"
|
|
||||||
#include "bat_debugfs.h"
|
|
||||||
#include "translation-table.h"
|
|
||||||
#include "types.h"
|
|
||||||
#include "hash.h"
|
|
||||||
#include "send.h"
|
|
||||||
#include "bat_sysfs.h"
|
|
||||||
#include <linux/slab.h>
|
|
||||||
#include <linux/ethtool.h>
|
|
||||||
#include <linux/etherdevice.h>
|
|
||||||
#include "unicast.h"
|
|
||||||
|
|
||||||
|
|
||||||
static int bat_get_settings(struct net_device *dev, struct ethtool_cmd *cmd);
|
|
||||||
static void bat_get_drvinfo(struct net_device *dev,
|
|
||||||
struct ethtool_drvinfo *info);
|
|
||||||
static u32 bat_get_msglevel(struct net_device *dev);
|
|
||||||
static void bat_set_msglevel(struct net_device *dev, u32 value);
|
|
||||||
static u32 bat_get_link(struct net_device *dev);
|
|
||||||
static u32 bat_get_rx_csum(struct net_device *dev);
|
|
||||||
static int bat_set_rx_csum(struct net_device *dev, u32 data);
|
|
||||||
|
|
||||||
static const struct ethtool_ops bat_ethtool_ops = {
|
|
||||||
.get_settings = bat_get_settings,
|
|
||||||
.get_drvinfo = bat_get_drvinfo,
|
|
||||||
.get_msglevel = bat_get_msglevel,
|
|
||||||
.set_msglevel = bat_set_msglevel,
|
|
||||||
.get_link = bat_get_link,
|
|
||||||
.get_rx_csum = bat_get_rx_csum,
|
|
||||||
.set_rx_csum = bat_set_rx_csum
|
|
||||||
};
|
|
||||||
|
|
||||||
int my_skb_head_push(struct sk_buff *skb, unsigned int len)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO: We must check if we can release all references to non-payload
|
|
||||||
* data using skb_header_release in our skbs to allow skb_cow_header to
|
|
||||||
* work optimally. This means that those skbs are not allowed to read
|
|
||||||
* or write any data which is before the current position of skb->data
|
|
||||||
* after that call and thus allow other skbs with the same data buffer
|
|
||||||
* to write freely in that area.
|
|
||||||
*/
|
|
||||||
result = skb_cow_head(skb, len);
|
|
||||||
if (result < 0)
|
|
||||||
return result;
|
|
||||||
|
|
||||||
skb_push(skb, len);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int interface_open(struct net_device *dev)
|
|
||||||
{
|
|
||||||
netif_start_queue(dev);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int interface_release(struct net_device *dev)
|
|
||||||
{
|
|
||||||
netif_stop_queue(dev);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct net_device_stats *interface_stats(struct net_device *dev)
|
|
||||||
{
|
|
||||||
struct bat_priv *bat_priv = netdev_priv(dev);
|
|
||||||
return &bat_priv->stats;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int interface_set_mac_addr(struct net_device *dev, void *p)
|
|
||||||
{
|
|
||||||
struct bat_priv *bat_priv = netdev_priv(dev);
|
|
||||||
struct sockaddr *addr = p;
|
|
||||||
|
|
||||||
if (!is_valid_ether_addr(addr->sa_data))
|
|
||||||
return -EADDRNOTAVAIL;
|
|
||||||
|
|
||||||
/* only modify hna-table if it has been initialised before */
|
|
||||||
if (atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE) {
|
|
||||||
hna_local_remove(bat_priv, dev->dev_addr,
|
|
||||||
"mac address changed");
|
|
||||||
hna_local_add(dev, addr->sa_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int interface_change_mtu(struct net_device *dev, int new_mtu)
|
|
||||||
{
|
|
||||||
/* check ranges */
|
|
||||||
if ((new_mtu < 68) || (new_mtu > hardif_min_mtu(dev)))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
dev->mtu = new_mtu;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
|
|
||||||
{
|
|
||||||
struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
|
|
||||||
struct bat_priv *bat_priv = netdev_priv(soft_iface);
|
|
||||||
struct bcast_packet *bcast_packet;
|
|
||||||
int data_len = skb->len, ret;
|
|
||||||
|
|
||||||
if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE)
|
|
||||||
goto dropped;
|
|
||||||
|
|
||||||
soft_iface->trans_start = jiffies;
|
|
||||||
|
|
||||||
/* TODO: check this for locks */
|
|
||||||
hna_local_add(soft_iface, ethhdr->h_source);
|
|
||||||
|
|
||||||
/* ethernet packet should be broadcasted */
|
|
||||||
if (is_bcast(ethhdr->h_dest) || is_mcast(ethhdr->h_dest)) {
|
|
||||||
if (!bat_priv->primary_if)
|
|
||||||
goto dropped;
|
|
||||||
|
|
||||||
if (my_skb_head_push(skb, sizeof(struct bcast_packet)) < 0)
|
|
||||||
goto dropped;
|
|
||||||
|
|
||||||
bcast_packet = (struct bcast_packet *)skb->data;
|
|
||||||
bcast_packet->version = COMPAT_VERSION;
|
|
||||||
bcast_packet->ttl = TTL;
|
|
||||||
|
|
||||||
/* batman packet type: broadcast */
|
|
||||||
bcast_packet->packet_type = BAT_BCAST;
|
|
||||||
|
|
||||||
/* hw address of first interface is the orig mac because only
|
|
||||||
* this mac is known throughout the mesh */
|
|
||||||
memcpy(bcast_packet->orig,
|
|
||||||
bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
|
|
||||||
|
|
||||||
/* set broadcast sequence number */
|
|
||||||
bcast_packet->seqno =
|
|
||||||
htonl(atomic_inc_return(&bat_priv->bcast_seqno));
|
|
||||||
|
|
||||||
add_bcast_packet_to_list(bat_priv, skb);
|
|
||||||
|
|
||||||
/* a copy is stored in the bcast list, therefore removing
|
|
||||||
* the original skb. */
|
|
||||||
kfree_skb(skb);
|
|
||||||
|
|
||||||
/* unicast packet */
|
|
||||||
} else {
|
|
||||||
ret = unicast_send_skb(skb, bat_priv);
|
|
||||||
if (ret != 0)
|
|
||||||
goto dropped_freed;
|
|
||||||
}
|
|
||||||
|
|
||||||
bat_priv->stats.tx_packets++;
|
|
||||||
bat_priv->stats.tx_bytes += data_len;
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
dropped:
|
|
||||||
kfree_skb(skb);
|
|
||||||
dropped_freed:
|
|
||||||
bat_priv->stats.tx_dropped++;
|
|
||||||
end:
|
|
||||||
return NETDEV_TX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void interface_rx(struct net_device *soft_iface,
|
|
||||||
struct sk_buff *skb, int hdr_size)
|
|
||||||
{
|
|
||||||
struct bat_priv *priv = netdev_priv(soft_iface);
|
|
||||||
|
|
||||||
/* check if enough space is available for pulling, and pull */
|
|
||||||
if (!pskb_may_pull(skb, hdr_size))
|
|
||||||
goto dropped;
|
|
||||||
|
|
||||||
skb_pull_rcsum(skb, hdr_size);
|
|
||||||
/* skb_set_mac_header(skb, -sizeof(struct ethhdr));*/
|
|
||||||
|
|
||||||
/* skb->dev & skb->pkt_type are set here */
|
|
||||||
if (unlikely(!pskb_may_pull(skb, ETH_HLEN)))
|
|
||||||
goto dropped;
|
|
||||||
skb->protocol = eth_type_trans(skb, soft_iface);
|
|
||||||
|
|
||||||
/* should not be neccesary anymore as we use skb_pull_rcsum()
|
|
||||||
* TODO: please verify this and remove this TODO
|
|
||||||
* -- Dec 21st 2009, Simon Wunderlich */
|
|
||||||
|
|
||||||
/* skb->ip_summed = CHECKSUM_UNNECESSARY;*/
|
|
||||||
|
|
||||||
priv->stats.rx_packets++;
|
|
||||||
priv->stats.rx_bytes += skb->len + sizeof(struct ethhdr);
|
|
||||||
|
|
||||||
soft_iface->last_rx = jiffies;
|
|
||||||
|
|
||||||
netif_rx(skb);
|
|
||||||
return;
|
|
||||||
|
|
||||||
dropped:
|
|
||||||
kfree_skb(skb);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAVE_NET_DEVICE_OPS
|
|
||||||
static const struct net_device_ops bat_netdev_ops = {
|
|
||||||
.ndo_open = interface_open,
|
|
||||||
.ndo_stop = interface_release,
|
|
||||||
.ndo_get_stats = interface_stats,
|
|
||||||
.ndo_set_mac_address = interface_set_mac_addr,
|
|
||||||
.ndo_change_mtu = interface_change_mtu,
|
|
||||||
.ndo_start_xmit = interface_tx,
|
|
||||||
.ndo_validate_addr = eth_validate_addr
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void interface_setup(struct net_device *dev)
|
|
||||||
{
|
|
||||||
struct bat_priv *priv = netdev_priv(dev);
|
|
||||||
char dev_addr[ETH_ALEN];
|
|
||||||
|
|
||||||
ether_setup(dev);
|
|
||||||
|
|
||||||
#ifdef HAVE_NET_DEVICE_OPS
|
|
||||||
dev->netdev_ops = &bat_netdev_ops;
|
|
||||||
#else
|
|
||||||
dev->open = interface_open;
|
|
||||||
dev->stop = interface_release;
|
|
||||||
dev->get_stats = interface_stats;
|
|
||||||
dev->set_mac_address = interface_set_mac_addr;
|
|
||||||
dev->change_mtu = interface_change_mtu;
|
|
||||||
dev->hard_start_xmit = interface_tx;
|
|
||||||
#endif
|
|
||||||
dev->destructor = free_netdev;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* can't call min_mtu, because the needed variables
|
|
||||||
* have not been initialized yet
|
|
||||||
*/
|
|
||||||
dev->mtu = ETH_DATA_LEN;
|
|
||||||
dev->hard_header_len = BAT_HEADER_LEN; /* reserve more space in the
|
|
||||||
* skbuff for our header */
|
|
||||||
|
|
||||||
/* generate random address */
|
|
||||||
random_ether_addr(dev_addr);
|
|
||||||
memcpy(dev->dev_addr, dev_addr, ETH_ALEN);
|
|
||||||
|
|
||||||
SET_ETHTOOL_OPS(dev, &bat_ethtool_ops);
|
|
||||||
|
|
||||||
memset(priv, 0, sizeof(struct bat_priv));
|
|
||||||
}
|
|
||||||
|
|
||||||
struct net_device *softif_create(char *name)
|
|
||||||
{
|
|
||||||
struct net_device *soft_iface;
|
|
||||||
struct bat_priv *bat_priv;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
soft_iface = alloc_netdev(sizeof(struct bat_priv) , name,
|
|
||||||
interface_setup);
|
|
||||||
|
|
||||||
if (!soft_iface) {
|
|
||||||
pr_err("Unable to allocate the batman interface: %s\n", name);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = register_netdev(soft_iface);
|
|
||||||
if (ret < 0) {
|
|
||||||
pr_err("Unable to register the batman interface '%s': %i\n",
|
|
||||||
name, ret);
|
|
||||||
goto free_soft_iface;
|
|
||||||
}
|
|
||||||
|
|
||||||
bat_priv = netdev_priv(soft_iface);
|
|
||||||
|
|
||||||
atomic_set(&bat_priv->aggregation_enabled, 1);
|
|
||||||
atomic_set(&bat_priv->bonding_enabled, 0);
|
|
||||||
atomic_set(&bat_priv->vis_mode, VIS_TYPE_CLIENT_UPDATE);
|
|
||||||
atomic_set(&bat_priv->orig_interval, 1000);
|
|
||||||
atomic_set(&bat_priv->log_level, 0);
|
|
||||||
atomic_set(&bat_priv->frag_enabled, 1);
|
|
||||||
atomic_set(&bat_priv->bcast_queue_left, BCAST_QUEUE_LEN);
|
|
||||||
atomic_set(&bat_priv->batman_queue_left, BATMAN_QUEUE_LEN);
|
|
||||||
|
|
||||||
atomic_set(&bat_priv->mesh_state, MESH_INACTIVE);
|
|
||||||
atomic_set(&bat_priv->bcast_seqno, 1);
|
|
||||||
atomic_set(&bat_priv->hna_local_changed, 0);
|
|
||||||
|
|
||||||
bat_priv->primary_if = NULL;
|
|
||||||
bat_priv->num_ifaces = 0;
|
|
||||||
|
|
||||||
ret = sysfs_add_meshif(soft_iface);
|
|
||||||
if (ret < 0)
|
|
||||||
goto unreg_soft_iface;
|
|
||||||
|
|
||||||
ret = debugfs_add_meshif(soft_iface);
|
|
||||||
if (ret < 0)
|
|
||||||
goto unreg_sysfs;
|
|
||||||
|
|
||||||
ret = mesh_init(soft_iface);
|
|
||||||
if (ret < 0)
|
|
||||||
goto unreg_debugfs;
|
|
||||||
|
|
||||||
return soft_iface;
|
|
||||||
|
|
||||||
unreg_debugfs:
|
|
||||||
debugfs_del_meshif(soft_iface);
|
|
||||||
unreg_sysfs:
|
|
||||||
sysfs_del_meshif(soft_iface);
|
|
||||||
unreg_soft_iface:
|
|
||||||
unregister_netdev(soft_iface);
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
free_soft_iface:
|
|
||||||
free_netdev(soft_iface);
|
|
||||||
out:
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void softif_destroy(struct net_device *soft_iface)
|
|
||||||
{
|
|
||||||
debugfs_del_meshif(soft_iface);
|
|
||||||
sysfs_del_meshif(soft_iface);
|
|
||||||
mesh_free(soft_iface);
|
|
||||||
unregister_netdevice(soft_iface);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ethtool */
|
|
||||||
static int bat_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
|
|
||||||
{
|
|
||||||
cmd->supported = 0;
|
|
||||||
cmd->advertising = 0;
|
|
||||||
cmd->speed = SPEED_10;
|
|
||||||
cmd->duplex = DUPLEX_FULL;
|
|
||||||
cmd->port = PORT_TP;
|
|
||||||
cmd->phy_address = 0;
|
|
||||||
cmd->transceiver = XCVR_INTERNAL;
|
|
||||||
cmd->autoneg = AUTONEG_DISABLE;
|
|
||||||
cmd->maxtxpkt = 0;
|
|
||||||
cmd->maxrxpkt = 0;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void bat_get_drvinfo(struct net_device *dev,
|
|
||||||
struct ethtool_drvinfo *info)
|
|
||||||
{
|
|
||||||
strcpy(info->driver, "B.A.T.M.A.N. advanced");
|
|
||||||
strcpy(info->version, SOURCE_VERSION);
|
|
||||||
strcpy(info->fw_version, "N/A");
|
|
||||||
strcpy(info->bus_info, "batman");
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 bat_get_msglevel(struct net_device *dev)
|
|
||||||
{
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void bat_set_msglevel(struct net_device *dev, u32 value)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 bat_get_link(struct net_device *dev)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 bat_get_rx_csum(struct net_device *dev)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int bat_set_rx_csum(struct net_device *dev, u32 data)
|
|
||||||
{
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
|
|
||||||
*
|
|
||||||
* Marek Lindner
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of version 2 of the GNU General Public
|
|
||||||
* License as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
||||||
* 02110-1301, USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _NET_BATMAN_ADV_SOFT_INTERFACE_H_
|
|
||||||
#define _NET_BATMAN_ADV_SOFT_INTERFACE_H_
|
|
||||||
|
|
||||||
int my_skb_head_push(struct sk_buff *skb, unsigned int len);
|
|
||||||
int interface_tx(struct sk_buff *skb, struct net_device *soft_iface);
|
|
||||||
void interface_rx(struct net_device *soft_iface,
|
|
||||||
struct sk_buff *skb, int hdr_size);
|
|
||||||
struct net_device *softif_create(char *name);
|
|
||||||
void softif_destroy(struct net_device *soft_iface);
|
|
||||||
|
|
||||||
#endif /* _NET_BATMAN_ADV_SOFT_INTERFACE_H_ */
|
|
@ -1,14 +0,0 @@
|
|||||||
|
|
||||||
What: /sys/class/net/<iface>/batman-adv/mesh_iface
|
|
||||||
Date: May 2010
|
|
||||||
Contact: Marek Lindner <lindner_marek@yahoo.de>
|
|
||||||
Description:
|
|
||||||
The /sys/class/net/<iface>/batman-adv/mesh_iface file
|
|
||||||
displays the batman mesh interface this <iface>
|
|
||||||
currently is associated with.
|
|
||||||
|
|
||||||
What: /sys/class/net/<iface>/batman-adv/iface_status
|
|
||||||
Date: May 2010
|
|
||||||
Contact: Marek Lindner <lindner_marek@yahoo.de>
|
|
||||||
Description:
|
|
||||||
Indicates the status of <iface> as it is seen by batman.
|
|
@ -1,41 +0,0 @@
|
|||||||
|
|
||||||
What: /sys/class/net/<mesh_iface>/mesh/aggregated_ogms
|
|
||||||
Date: May 2010
|
|
||||||
Contact: Marek Lindner <lindner_marek@yahoo.de>
|
|
||||||
Description:
|
|
||||||
Indicates whether the batman protocol messages of the
|
|
||||||
mesh <mesh_iface> shall be aggregated or not.
|
|
||||||
|
|
||||||
What: /sys/class/net/<mesh_iface>/mesh/bonding
|
|
||||||
Date: June 2010
|
|
||||||
Contact: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
|
|
||||||
Description:
|
|
||||||
Indicates whether the data traffic going through the
|
|
||||||
mesh will be sent using multiple interfaces at the
|
|
||||||
same time (if available).
|
|
||||||
|
|
||||||
What: /sys/class/net/<mesh_iface>/mesh/fragmentation
|
|
||||||
Date: October 2010
|
|
||||||
Contact: Andreas Langer <an.langer@gmx.de>
|
|
||||||
Description:
|
|
||||||
Indicates whether the data traffic going through the
|
|
||||||
mesh will be fragmented or silently discarded if the
|
|
||||||
packet size exceeds the outgoing interface MTU.
|
|
||||||
|
|
||||||
What: /sys/class/net/<mesh_iface>/mesh/orig_interval
|
|
||||||
Date: May 2010
|
|
||||||
Contact: Marek Lindner <lindner_marek@yahoo.de>
|
|
||||||
Description:
|
|
||||||
Defines the interval in milliseconds in which batman
|
|
||||||
sends its protocol messages.
|
|
||||||
|
|
||||||
What: /sys/class/net/<mesh_iface>/mesh/vis_mode
|
|
||||||
Date: May 2010
|
|
||||||
Contact: Marek Lindner <lindner_marek@yahoo.de>
|
|
||||||
Description:
|
|
||||||
Each batman node only maintains information about its
|
|
||||||
own local neighborhood, therefore generating graphs
|
|
||||||
showing the topology of the entire mesh is not easily
|
|
||||||
feasible without having a central instance to collect
|
|
||||||
the local topologies from all nodes. This file allows
|
|
||||||
to activate the collecting (server) mode.
|
|
@ -1,518 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
|
|
||||||
*
|
|
||||||
* Marek Lindner, Simon Wunderlich
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of version 2 of the GNU General Public
|
|
||||||
* License as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
||||||
* 02110-1301, USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "main.h"
|
|
||||||
#include "translation-table.h"
|
|
||||||
#include "soft-interface.h"
|
|
||||||
#include "types.h"
|
|
||||||
#include "hash.h"
|
|
||||||
|
|
||||||
static void hna_local_purge(struct work_struct *work);
|
|
||||||
static void _hna_global_del_orig(struct bat_priv *bat_priv,
|
|
||||||
struct hna_global_entry *hna_global_entry,
|
|
||||||
char *message);
|
|
||||||
|
|
||||||
static void hna_local_start_timer(struct bat_priv *bat_priv)
|
|
||||||
{
|
|
||||||
INIT_DELAYED_WORK(&bat_priv->hna_work, hna_local_purge);
|
|
||||||
queue_delayed_work(bat_event_workqueue, &bat_priv->hna_work, 10 * HZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
int hna_local_init(struct bat_priv *bat_priv)
|
|
||||||
{
|
|
||||||
if (bat_priv->hna_local_hash)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
bat_priv->hna_local_hash = hash_new(128, compare_orig, choose_orig);
|
|
||||||
|
|
||||||
if (!bat_priv->hna_local_hash)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
atomic_set(&bat_priv->hna_local_changed, 0);
|
|
||||||
hna_local_start_timer(bat_priv);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void hna_local_add(struct net_device *soft_iface, uint8_t *addr)
|
|
||||||
{
|
|
||||||
struct bat_priv *bat_priv = netdev_priv(soft_iface);
|
|
||||||
struct hna_local_entry *hna_local_entry;
|
|
||||||
struct hna_global_entry *hna_global_entry;
|
|
||||||
struct hashtable_t *swaphash;
|
|
||||||
unsigned long flags;
|
|
||||||
int required_bytes;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&bat_priv->hna_lhash_lock, flags);
|
|
||||||
hna_local_entry =
|
|
||||||
((struct hna_local_entry *)hash_find(bat_priv->hna_local_hash,
|
|
||||||
addr));
|
|
||||||
spin_unlock_irqrestore(&bat_priv->hna_lhash_lock, flags);
|
|
||||||
|
|
||||||
if (hna_local_entry) {
|
|
||||||
hna_local_entry->last_seen = jiffies;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* only announce as many hosts as possible in the batman-packet and
|
|
||||||
space in batman_packet->num_hna That also should give a limit to
|
|
||||||
MAC-flooding. */
|
|
||||||
required_bytes = (bat_priv->num_local_hna + 1) * ETH_ALEN;
|
|
||||||
required_bytes += BAT_PACKET_LEN;
|
|
||||||
|
|
||||||
if ((required_bytes > ETH_DATA_LEN) ||
|
|
||||||
(atomic_read(&bat_priv->aggregation_enabled) &&
|
|
||||||
required_bytes > MAX_AGGREGATION_BYTES) ||
|
|
||||||
(bat_priv->num_local_hna + 1 > 255)) {
|
|
||||||
bat_dbg(DBG_ROUTES, bat_priv,
|
|
||||||
"Can't add new local hna entry (%pM): "
|
|
||||||
"number of local hna entries exceeds packet size\n",
|
|
||||||
addr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bat_dbg(DBG_ROUTES, bat_priv,
|
|
||||||
"Creating new local hna entry: %pM\n", addr);
|
|
||||||
|
|
||||||
hna_local_entry = kmalloc(sizeof(struct hna_local_entry), GFP_ATOMIC);
|
|
||||||
if (!hna_local_entry)
|
|
||||||
return;
|
|
||||||
|
|
||||||
memcpy(hna_local_entry->addr, addr, ETH_ALEN);
|
|
||||||
hna_local_entry->last_seen = jiffies;
|
|
||||||
|
|
||||||
/* the batman interface mac address should never be purged */
|
|
||||||
if (compare_orig(addr, soft_iface->dev_addr))
|
|
||||||
hna_local_entry->never_purge = 1;
|
|
||||||
else
|
|
||||||
hna_local_entry->never_purge = 0;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&bat_priv->hna_lhash_lock, flags);
|
|
||||||
|
|
||||||
hash_add(bat_priv->hna_local_hash, hna_local_entry);
|
|
||||||
bat_priv->num_local_hna++;
|
|
||||||
atomic_set(&bat_priv->hna_local_changed, 1);
|
|
||||||
|
|
||||||
if (bat_priv->hna_local_hash->elements * 4 >
|
|
||||||
bat_priv->hna_local_hash->size) {
|
|
||||||
swaphash = hash_resize(bat_priv->hna_local_hash,
|
|
||||||
bat_priv->hna_local_hash->size * 2);
|
|
||||||
|
|
||||||
if (!swaphash)
|
|
||||||
pr_err("Couldn't resize local hna hash table\n");
|
|
||||||
else
|
|
||||||
bat_priv->hna_local_hash = swaphash;
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&bat_priv->hna_lhash_lock, flags);
|
|
||||||
|
|
||||||
/* remove address from global hash if present */
|
|
||||||
spin_lock_irqsave(&bat_priv->hna_ghash_lock, flags);
|
|
||||||
|
|
||||||
hna_global_entry = ((struct hna_global_entry *)
|
|
||||||
hash_find(bat_priv->hna_global_hash, addr));
|
|
||||||
|
|
||||||
if (hna_global_entry)
|
|
||||||
_hna_global_del_orig(bat_priv, hna_global_entry,
|
|
||||||
"local hna received");
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&bat_priv->hna_ghash_lock, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
int hna_local_fill_buffer(struct bat_priv *bat_priv,
|
|
||||||
unsigned char *buff, int buff_len)
|
|
||||||
{
|
|
||||||
struct hna_local_entry *hna_local_entry;
|
|
||||||
HASHIT(hashit);
|
|
||||||
int i = 0;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&bat_priv->hna_lhash_lock, flags);
|
|
||||||
|
|
||||||
while (hash_iterate(bat_priv->hna_local_hash, &hashit)) {
|
|
||||||
|
|
||||||
if (buff_len < (i + 1) * ETH_ALEN)
|
|
||||||
break;
|
|
||||||
|
|
||||||
hna_local_entry = hashit.bucket->data;
|
|
||||||
memcpy(buff + (i * ETH_ALEN), hna_local_entry->addr, ETH_ALEN);
|
|
||||||
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if we did not get all new local hnas see you next time ;-) */
|
|
||||||
if (i == bat_priv->num_local_hna)
|
|
||||||
atomic_set(&bat_priv->hna_local_changed, 0);
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&bat_priv->hna_lhash_lock, flags);
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
int hna_local_seq_print_text(struct seq_file *seq, void *offset)
|
|
||||||
{
|
|
||||||
struct net_device *net_dev = (struct net_device *)seq->private;
|
|
||||||
struct bat_priv *bat_priv = netdev_priv(net_dev);
|
|
||||||
struct hna_local_entry *hna_local_entry;
|
|
||||||
HASHIT(hashit);
|
|
||||||
HASHIT(hashit_count);
|
|
||||||
unsigned long flags;
|
|
||||||
size_t buf_size, pos;
|
|
||||||
char *buff;
|
|
||||||
|
|
||||||
if (!bat_priv->primary_if) {
|
|
||||||
return seq_printf(seq, "BATMAN mesh %s disabled - "
|
|
||||||
"please specify interfaces to enable it\n",
|
|
||||||
net_dev->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
seq_printf(seq, "Locally retrieved addresses (from %s) "
|
|
||||||
"announced via HNA:\n",
|
|
||||||
net_dev->name);
|
|
||||||
|
|
||||||
spin_lock_irqsave(&bat_priv->hna_lhash_lock, flags);
|
|
||||||
|
|
||||||
buf_size = 1;
|
|
||||||
/* Estimate length for: " * xx:xx:xx:xx:xx:xx\n" */
|
|
||||||
while (hash_iterate(bat_priv->hna_local_hash, &hashit_count))
|
|
||||||
buf_size += 21;
|
|
||||||
|
|
||||||
buff = kmalloc(buf_size, GFP_ATOMIC);
|
|
||||||
if (!buff) {
|
|
||||||
spin_unlock_irqrestore(&bat_priv->hna_lhash_lock, flags);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
buff[0] = '\0';
|
|
||||||
pos = 0;
|
|
||||||
|
|
||||||
while (hash_iterate(bat_priv->hna_local_hash, &hashit)) {
|
|
||||||
hna_local_entry = hashit.bucket->data;
|
|
||||||
|
|
||||||
pos += snprintf(buff + pos, 22, " * %pM\n",
|
|
||||||
hna_local_entry->addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&bat_priv->hna_lhash_lock, flags);
|
|
||||||
|
|
||||||
seq_printf(seq, "%s", buff);
|
|
||||||
kfree(buff);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _hna_local_del(void *data, void *arg)
|
|
||||||
{
|
|
||||||
struct bat_priv *bat_priv = (struct bat_priv *)arg;
|
|
||||||
|
|
||||||
kfree(data);
|
|
||||||
bat_priv->num_local_hna--;
|
|
||||||
atomic_set(&bat_priv->hna_local_changed, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void hna_local_del(struct bat_priv *bat_priv,
|
|
||||||
struct hna_local_entry *hna_local_entry,
|
|
||||||
char *message)
|
|
||||||
{
|
|
||||||
bat_dbg(DBG_ROUTES, bat_priv, "Deleting local hna entry (%pM): %s\n",
|
|
||||||
hna_local_entry->addr, message);
|
|
||||||
|
|
||||||
hash_remove(bat_priv->hna_local_hash, hna_local_entry->addr);
|
|
||||||
_hna_local_del(hna_local_entry, bat_priv);
|
|
||||||
}
|
|
||||||
|
|
||||||
void hna_local_remove(struct bat_priv *bat_priv,
|
|
||||||
uint8_t *addr, char *message)
|
|
||||||
{
|
|
||||||
struct hna_local_entry *hna_local_entry;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&bat_priv->hna_lhash_lock, flags);
|
|
||||||
|
|
||||||
hna_local_entry = (struct hna_local_entry *)
|
|
||||||
hash_find(bat_priv->hna_local_hash, addr);
|
|
||||||
if (hna_local_entry)
|
|
||||||
hna_local_del(bat_priv, hna_local_entry, message);
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&bat_priv->hna_lhash_lock, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void hna_local_purge(struct work_struct *work)
|
|
||||||
{
|
|
||||||
struct delayed_work *delayed_work =
|
|
||||||
container_of(work, struct delayed_work, work);
|
|
||||||
struct bat_priv *bat_priv =
|
|
||||||
container_of(delayed_work, struct bat_priv, hna_work);
|
|
||||||
struct hna_local_entry *hna_local_entry;
|
|
||||||
HASHIT(hashit);
|
|
||||||
unsigned long flags;
|
|
||||||
unsigned long timeout;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&bat_priv->hna_lhash_lock, flags);
|
|
||||||
|
|
||||||
while (hash_iterate(bat_priv->hna_local_hash, &hashit)) {
|
|
||||||
hna_local_entry = hashit.bucket->data;
|
|
||||||
|
|
||||||
timeout = hna_local_entry->last_seen + LOCAL_HNA_TIMEOUT * HZ;
|
|
||||||
|
|
||||||
if ((!hna_local_entry->never_purge) &&
|
|
||||||
time_after(jiffies, timeout))
|
|
||||||
hna_local_del(bat_priv, hna_local_entry,
|
|
||||||
"address timed out");
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&bat_priv->hna_lhash_lock, flags);
|
|
||||||
hna_local_start_timer(bat_priv);
|
|
||||||
}
|
|
||||||
|
|
||||||
void hna_local_free(struct bat_priv *bat_priv)
|
|
||||||
{
|
|
||||||
if (!bat_priv->hna_local_hash)
|
|
||||||
return;
|
|
||||||
|
|
||||||
cancel_delayed_work_sync(&bat_priv->hna_work);
|
|
||||||
hash_delete(bat_priv->hna_local_hash, _hna_local_del, bat_priv);
|
|
||||||
bat_priv->hna_local_hash = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int hna_global_init(struct bat_priv *bat_priv)
|
|
||||||
{
|
|
||||||
if (bat_priv->hna_global_hash)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
bat_priv->hna_global_hash = hash_new(128, compare_orig, choose_orig);
|
|
||||||
|
|
||||||
if (!bat_priv->hna_global_hash)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void hna_global_add_orig(struct bat_priv *bat_priv,
|
|
||||||
struct orig_node *orig_node,
|
|
||||||
unsigned char *hna_buff, int hna_buff_len)
|
|
||||||
{
|
|
||||||
struct hna_global_entry *hna_global_entry;
|
|
||||||
struct hna_local_entry *hna_local_entry;
|
|
||||||
struct hashtable_t *swaphash;
|
|
||||||
int hna_buff_count = 0;
|
|
||||||
unsigned long flags;
|
|
||||||
unsigned char *hna_ptr;
|
|
||||||
|
|
||||||
while ((hna_buff_count + 1) * ETH_ALEN <= hna_buff_len) {
|
|
||||||
spin_lock_irqsave(&bat_priv->hna_ghash_lock, flags);
|
|
||||||
|
|
||||||
hna_ptr = hna_buff + (hna_buff_count * ETH_ALEN);
|
|
||||||
hna_global_entry = (struct hna_global_entry *)
|
|
||||||
hash_find(bat_priv->hna_global_hash, hna_ptr);
|
|
||||||
|
|
||||||
if (!hna_global_entry) {
|
|
||||||
spin_unlock_irqrestore(&bat_priv->hna_ghash_lock,
|
|
||||||
flags);
|
|
||||||
|
|
||||||
hna_global_entry =
|
|
||||||
kmalloc(sizeof(struct hna_global_entry),
|
|
||||||
GFP_ATOMIC);
|
|
||||||
|
|
||||||
if (!hna_global_entry)
|
|
||||||
break;
|
|
||||||
|
|
||||||
memcpy(hna_global_entry->addr, hna_ptr, ETH_ALEN);
|
|
||||||
|
|
||||||
bat_dbg(DBG_ROUTES, bat_priv,
|
|
||||||
"Creating new global hna entry: "
|
|
||||||
"%pM (via %pM)\n",
|
|
||||||
hna_global_entry->addr, orig_node->orig);
|
|
||||||
|
|
||||||
spin_lock_irqsave(&bat_priv->hna_ghash_lock, flags);
|
|
||||||
hash_add(bat_priv->hna_global_hash, hna_global_entry);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
hna_global_entry->orig_node = orig_node;
|
|
||||||
spin_unlock_irqrestore(&bat_priv->hna_ghash_lock, flags);
|
|
||||||
|
|
||||||
/* remove address from local hash if present */
|
|
||||||
spin_lock_irqsave(&bat_priv->hna_lhash_lock, flags);
|
|
||||||
|
|
||||||
hna_ptr = hna_buff + (hna_buff_count * ETH_ALEN);
|
|
||||||
hna_local_entry = (struct hna_local_entry *)
|
|
||||||
hash_find(bat_priv->hna_local_hash, hna_ptr);
|
|
||||||
|
|
||||||
if (hna_local_entry)
|
|
||||||
hna_local_del(bat_priv, hna_local_entry,
|
|
||||||
"global hna received");
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&bat_priv->hna_lhash_lock, flags);
|
|
||||||
|
|
||||||
hna_buff_count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* initialize, and overwrite if malloc succeeds */
|
|
||||||
orig_node->hna_buff = NULL;
|
|
||||||
orig_node->hna_buff_len = 0;
|
|
||||||
|
|
||||||
if (hna_buff_len > 0) {
|
|
||||||
orig_node->hna_buff = kmalloc(hna_buff_len, GFP_ATOMIC);
|
|
||||||
if (orig_node->hna_buff) {
|
|
||||||
memcpy(orig_node->hna_buff, hna_buff, hna_buff_len);
|
|
||||||
orig_node->hna_buff_len = hna_buff_len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_lock_irqsave(&bat_priv->hna_ghash_lock, flags);
|
|
||||||
|
|
||||||
if (bat_priv->hna_global_hash->elements * 4 >
|
|
||||||
bat_priv->hna_global_hash->size) {
|
|
||||||
swaphash = hash_resize(bat_priv->hna_global_hash,
|
|
||||||
bat_priv->hna_global_hash->size * 2);
|
|
||||||
|
|
||||||
if (!swaphash)
|
|
||||||
pr_err("Couldn't resize global hna hash table\n");
|
|
||||||
else
|
|
||||||
bat_priv->hna_global_hash = swaphash;
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&bat_priv->hna_ghash_lock, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
int hna_global_seq_print_text(struct seq_file *seq, void *offset)
|
|
||||||
{
|
|
||||||
struct net_device *net_dev = (struct net_device *)seq->private;
|
|
||||||
struct bat_priv *bat_priv = netdev_priv(net_dev);
|
|
||||||
struct hna_global_entry *hna_global_entry;
|
|
||||||
HASHIT(hashit);
|
|
||||||
HASHIT(hashit_count);
|
|
||||||
unsigned long flags;
|
|
||||||
size_t buf_size, pos;
|
|
||||||
char *buff;
|
|
||||||
|
|
||||||
if (!bat_priv->primary_if) {
|
|
||||||
return seq_printf(seq, "BATMAN mesh %s disabled - "
|
|
||||||
"please specify interfaces to enable it\n",
|
|
||||||
net_dev->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
seq_printf(seq, "Globally announced HNAs received via the mesh %s\n",
|
|
||||||
net_dev->name);
|
|
||||||
|
|
||||||
spin_lock_irqsave(&bat_priv->hna_ghash_lock, flags);
|
|
||||||
|
|
||||||
buf_size = 1;
|
|
||||||
/* Estimate length for: " * xx:xx:xx:xx:xx:xx via xx:xx:xx:xx:xx:xx\n"*/
|
|
||||||
while (hash_iterate(bat_priv->hna_global_hash, &hashit_count))
|
|
||||||
buf_size += 43;
|
|
||||||
|
|
||||||
buff = kmalloc(buf_size, GFP_ATOMIC);
|
|
||||||
if (!buff) {
|
|
||||||
spin_unlock_irqrestore(&bat_priv->hna_ghash_lock, flags);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
buff[0] = '\0';
|
|
||||||
pos = 0;
|
|
||||||
|
|
||||||
while (hash_iterate(bat_priv->hna_global_hash, &hashit)) {
|
|
||||||
hna_global_entry = hashit.bucket->data;
|
|
||||||
|
|
||||||
pos += snprintf(buff + pos, 44,
|
|
||||||
" * %pM via %pM\n", hna_global_entry->addr,
|
|
||||||
hna_global_entry->orig_node->orig);
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&bat_priv->hna_ghash_lock, flags);
|
|
||||||
|
|
||||||
seq_printf(seq, "%s", buff);
|
|
||||||
kfree(buff);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _hna_global_del_orig(struct bat_priv *bat_priv,
|
|
||||||
struct hna_global_entry *hna_global_entry,
|
|
||||||
char *message)
|
|
||||||
{
|
|
||||||
bat_dbg(DBG_ROUTES, bat_priv,
|
|
||||||
"Deleting global hna entry %pM (via %pM): %s\n",
|
|
||||||
hna_global_entry->addr, hna_global_entry->orig_node->orig,
|
|
||||||
message);
|
|
||||||
|
|
||||||
hash_remove(bat_priv->hna_global_hash, hna_global_entry->addr);
|
|
||||||
kfree(hna_global_entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
void hna_global_del_orig(struct bat_priv *bat_priv,
|
|
||||||
struct orig_node *orig_node, char *message)
|
|
||||||
{
|
|
||||||
struct hna_global_entry *hna_global_entry;
|
|
||||||
int hna_buff_count = 0;
|
|
||||||
unsigned long flags;
|
|
||||||
unsigned char *hna_ptr;
|
|
||||||
|
|
||||||
if (orig_node->hna_buff_len == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&bat_priv->hna_ghash_lock, flags);
|
|
||||||
|
|
||||||
while ((hna_buff_count + 1) * ETH_ALEN <= orig_node->hna_buff_len) {
|
|
||||||
hna_ptr = orig_node->hna_buff + (hna_buff_count * ETH_ALEN);
|
|
||||||
hna_global_entry = (struct hna_global_entry *)
|
|
||||||
hash_find(bat_priv->hna_global_hash, hna_ptr);
|
|
||||||
|
|
||||||
if ((hna_global_entry) &&
|
|
||||||
(hna_global_entry->orig_node == orig_node))
|
|
||||||
_hna_global_del_orig(bat_priv, hna_global_entry,
|
|
||||||
message);
|
|
||||||
|
|
||||||
hna_buff_count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&bat_priv->hna_ghash_lock, flags);
|
|
||||||
|
|
||||||
orig_node->hna_buff_len = 0;
|
|
||||||
kfree(orig_node->hna_buff);
|
|
||||||
orig_node->hna_buff = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void hna_global_del(void *data, void *arg)
|
|
||||||
{
|
|
||||||
kfree(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void hna_global_free(struct bat_priv *bat_priv)
|
|
||||||
{
|
|
||||||
if (!bat_priv->hna_global_hash)
|
|
||||||
return;
|
|
||||||
|
|
||||||
hash_delete(bat_priv->hna_global_hash, hna_global_del, NULL);
|
|
||||||
bat_priv->hna_global_hash = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct orig_node *transtable_search(struct bat_priv *bat_priv, uint8_t *addr)
|
|
||||||
{
|
|
||||||
struct hna_global_entry *hna_global_entry;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&bat_priv->hna_ghash_lock, flags);
|
|
||||||
hna_global_entry = (struct hna_global_entry *)
|
|
||||||
hash_find(bat_priv->hna_global_hash, addr);
|
|
||||||
spin_unlock_irqrestore(&bat_priv->hna_ghash_lock, flags);
|
|
||||||
|
|
||||||
if (!hna_global_entry)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return hna_global_entry->orig_node;
|
|
||||||
}
|
|
@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
|
|
||||||
*
|
|
||||||
* Marek Lindner, Simon Wunderlich
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of version 2 of the GNU General Public
|
|
||||||
* License as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
||||||
* 02110-1301, USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _NET_BATMAN_ADV_TRANSLATION_TABLE_H_
|
|
||||||
#define _NET_BATMAN_ADV_TRANSLATION_TABLE_H_
|
|
||||||
|
|
||||||
#include "types.h"
|
|
||||||
|
|
||||||
int hna_local_init(struct bat_priv *bat_priv);
|
|
||||||
void hna_local_add(struct net_device *soft_iface, uint8_t *addr);
|
|
||||||
void hna_local_remove(struct bat_priv *bat_priv,
|
|
||||||
uint8_t *addr, char *message);
|
|
||||||
int hna_local_fill_buffer(struct bat_priv *bat_priv,
|
|
||||||
unsigned char *buff, int buff_len);
|
|
||||||
int hna_local_seq_print_text(struct seq_file *seq, void *offset);
|
|
||||||
void hna_local_free(struct bat_priv *bat_priv);
|
|
||||||
int hna_global_init(struct bat_priv *bat_priv);
|
|
||||||
void hna_global_add_orig(struct bat_priv *bat_priv,
|
|
||||||
struct orig_node *orig_node,
|
|
||||||
unsigned char *hna_buff, int hna_buff_len);
|
|
||||||
int hna_global_seq_print_text(struct seq_file *seq, void *offset);
|
|
||||||
void hna_global_del_orig(struct bat_priv *bat_priv,
|
|
||||||
struct orig_node *orig_node, char *message);
|
|
||||||
void hna_global_free(struct bat_priv *bat_priv);
|
|
||||||
struct orig_node *transtable_search(struct bat_priv *bat_priv, uint8_t *addr);
|
|
||||||
|
|
||||||
#endif /* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */
|
|
@ -1,241 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007-2010 B.A.T.M.A.N. contributors:
|
|
||||||
*
|
|
||||||
* Marek Lindner, Simon Wunderlich
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of version 2 of the GNU General Public
|
|
||||||
* License as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
||||||
* 02110-1301, USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _NET_BATMAN_ADV_TYPES_H_
|
|
||||||
#define _NET_BATMAN_ADV_TYPES_H_
|
|
||||||
|
|
||||||
#include "packet.h"
|
|
||||||
#include "bitarray.h"
|
|
||||||
|
|
||||||
#define BAT_HEADER_LEN (sizeof(struct ethhdr) + \
|
|
||||||
((sizeof(struct unicast_packet) > sizeof(struct bcast_packet) ? \
|
|
||||||
sizeof(struct unicast_packet) : \
|
|
||||||
sizeof(struct bcast_packet))))
|
|
||||||
|
|
||||||
|
|
||||||
struct batman_if {
|
|
||||||
struct list_head list;
|
|
||||||
int16_t if_num;
|
|
||||||
char if_status;
|
|
||||||
struct net_device *net_dev;
|
|
||||||
atomic_t seqno;
|
|
||||||
atomic_t frag_seqno;
|
|
||||||
unsigned char *packet_buff;
|
|
||||||
int packet_len;
|
|
||||||
struct kobject *hardif_obj;
|
|
||||||
atomic_t refcnt;
|
|
||||||
struct packet_type batman_adv_ptype;
|
|
||||||
struct net_device *soft_iface;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* orig_node - structure for orig_list maintaining nodes of mesh
|
|
||||||
* @primary_addr: hosts primary interface address
|
|
||||||
* @last_valid: when last packet from this node was received
|
|
||||||
* @bcast_seqno_reset: time when the broadcast seqno window was reset
|
|
||||||
* @batman_seqno_reset: time when the batman seqno window was reset
|
|
||||||
* @flags: for now only VIS_SERVER flag
|
|
||||||
* @last_real_seqno: last and best known squence number
|
|
||||||
* @last_ttl: ttl of last received packet
|
|
||||||
* @last_bcast_seqno: last broadcast sequence number received by this host
|
|
||||||
*
|
|
||||||
* @candidates: how many candidates are available
|
|
||||||
* @selected: next bonding candidate
|
|
||||||
*/
|
|
||||||
struct orig_node {
|
|
||||||
uint8_t orig[ETH_ALEN];
|
|
||||||
uint8_t primary_addr[ETH_ALEN];
|
|
||||||
struct neigh_node *router;
|
|
||||||
TYPE_OF_WORD *bcast_own;
|
|
||||||
uint8_t *bcast_own_sum;
|
|
||||||
uint8_t tq_own;
|
|
||||||
int tq_asym_penalty;
|
|
||||||
unsigned long last_valid;
|
|
||||||
unsigned long bcast_seqno_reset;
|
|
||||||
unsigned long batman_seqno_reset;
|
|
||||||
uint8_t flags;
|
|
||||||
unsigned char *hna_buff;
|
|
||||||
int16_t hna_buff_len;
|
|
||||||
uint32_t last_real_seqno;
|
|
||||||
uint8_t last_ttl;
|
|
||||||
TYPE_OF_WORD bcast_bits[NUM_WORDS];
|
|
||||||
uint32_t last_bcast_seqno;
|
|
||||||
struct list_head neigh_list;
|
|
||||||
struct list_head frag_list;
|
|
||||||
unsigned long last_frag_packet;
|
|
||||||
struct {
|
|
||||||
uint8_t candidates;
|
|
||||||
struct neigh_node *selected;
|
|
||||||
} bond;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* neigh_node
|
|
||||||
* @last_valid: when last packet via this neighbor was received
|
|
||||||
*/
|
|
||||||
struct neigh_node {
|
|
||||||
struct list_head list;
|
|
||||||
uint8_t addr[ETH_ALEN];
|
|
||||||
uint8_t real_packet_count;
|
|
||||||
uint8_t tq_recv[TQ_GLOBAL_WINDOW_SIZE];
|
|
||||||
uint8_t tq_index;
|
|
||||||
uint8_t tq_avg;
|
|
||||||
uint8_t last_ttl;
|
|
||||||
struct neigh_node *next_bond_candidate;
|
|
||||||
unsigned long last_valid;
|
|
||||||
TYPE_OF_WORD real_bits[NUM_WORDS];
|
|
||||||
struct orig_node *orig_node;
|
|
||||||
struct batman_if *if_incoming;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct bat_priv {
|
|
||||||
atomic_t mesh_state;
|
|
||||||
struct net_device_stats stats;
|
|
||||||
atomic_t aggregation_enabled;
|
|
||||||
atomic_t bonding_enabled;
|
|
||||||
atomic_t frag_enabled;
|
|
||||||
atomic_t vis_mode;
|
|
||||||
atomic_t orig_interval;
|
|
||||||
atomic_t log_level;
|
|
||||||
atomic_t bcast_seqno;
|
|
||||||
atomic_t bcast_queue_left;
|
|
||||||
atomic_t batman_queue_left;
|
|
||||||
char num_ifaces;
|
|
||||||
struct debug_log *debug_log;
|
|
||||||
struct batman_if *primary_if;
|
|
||||||
struct kobject *mesh_obj;
|
|
||||||
struct dentry *debug_dir;
|
|
||||||
struct hlist_head forw_bat_list;
|
|
||||||
struct hlist_head forw_bcast_list;
|
|
||||||
struct list_head vis_send_list;
|
|
||||||
struct hashtable_t *orig_hash;
|
|
||||||
struct hashtable_t *hna_local_hash;
|
|
||||||
struct hashtable_t *hna_global_hash;
|
|
||||||
struct hashtable_t *vis_hash;
|
|
||||||
spinlock_t orig_hash_lock; /* protects orig_hash */
|
|
||||||
spinlock_t forw_bat_list_lock; /* protects forw_bat_list */
|
|
||||||
spinlock_t forw_bcast_list_lock; /* protects */
|
|
||||||
spinlock_t hna_lhash_lock; /* protects hna_local_hash */
|
|
||||||
spinlock_t hna_ghash_lock; /* protects hna_global_hash */
|
|
||||||
spinlock_t vis_hash_lock; /* protects vis_hash */
|
|
||||||
spinlock_t vis_list_lock; /* protects vis_info::recv_list */
|
|
||||||
int16_t num_local_hna;
|
|
||||||
atomic_t hna_local_changed;
|
|
||||||
struct delayed_work hna_work;
|
|
||||||
struct delayed_work orig_work;
|
|
||||||
struct delayed_work vis_work;
|
|
||||||
struct vis_info *my_vis_info;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct socket_client {
|
|
||||||
struct list_head queue_list;
|
|
||||||
unsigned int queue_len;
|
|
||||||
unsigned char index;
|
|
||||||
spinlock_t lock; /* protects queue_list, queue_len, index */
|
|
||||||
wait_queue_head_t queue_wait;
|
|
||||||
struct bat_priv *bat_priv;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct socket_packet {
|
|
||||||
struct list_head list;
|
|
||||||
size_t icmp_len;
|
|
||||||
struct icmp_packet_rr icmp_packet;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct hna_local_entry {
|
|
||||||
uint8_t addr[ETH_ALEN];
|
|
||||||
unsigned long last_seen;
|
|
||||||
char never_purge;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct hna_global_entry {
|
|
||||||
uint8_t addr[ETH_ALEN];
|
|
||||||
struct orig_node *orig_node;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* forw_packet - structure for forw_list maintaining packets to be
|
|
||||||
* send/forwarded
|
|
||||||
*/
|
|
||||||
struct forw_packet {
|
|
||||||
struct hlist_node list;
|
|
||||||
unsigned long send_time;
|
|
||||||
uint8_t own;
|
|
||||||
struct sk_buff *skb;
|
|
||||||
uint16_t packet_len;
|
|
||||||
uint32_t direct_link_flags;
|
|
||||||
uint8_t num_packets;
|
|
||||||
struct delayed_work delayed_work;
|
|
||||||
struct batman_if *if_incoming;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* While scanning for vis-entries of a particular vis-originator
|
|
||||||
* this list collects its interfaces to create a subgraph/cluster
|
|
||||||
* out of them later
|
|
||||||
*/
|
|
||||||
struct if_list_entry {
|
|
||||||
uint8_t addr[ETH_ALEN];
|
|
||||||
bool primary;
|
|
||||||
struct hlist_node list;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct debug_log {
|
|
||||||
char log_buff[LOG_BUF_LEN];
|
|
||||||
unsigned long log_start;
|
|
||||||
unsigned long log_end;
|
|
||||||
spinlock_t lock; /* protects log_buff, log_start and log_end */
|
|
||||||
wait_queue_head_t queue_wait;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct frag_packet_list_entry {
|
|
||||||
struct list_head list;
|
|
||||||
uint16_t seqno;
|
|
||||||
struct sk_buff *skb;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct vis_info {
|
|
||||||
unsigned long first_seen;
|
|
||||||
struct list_head recv_list;
|
|
||||||
/* list of server-neighbors we received a vis-packet
|
|
||||||
* from. we should not reply to them. */
|
|
||||||
struct list_head send_list;
|
|
||||||
struct kref refcount;
|
|
||||||
struct bat_priv *bat_priv;
|
|
||||||
/* this packet might be part of the vis send queue. */
|
|
||||||
struct sk_buff *skb_packet;
|
|
||||||
/* vis_info may follow here*/
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
struct vis_info_entry {
|
|
||||||
uint8_t src[ETH_ALEN];
|
|
||||||
uint8_t dest[ETH_ALEN];
|
|
||||||
uint8_t quality; /* quality = 0 means HNA */
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
struct recvlist_node {
|
|
||||||
struct list_head list;
|
|
||||||
uint8_t mac[ETH_ALEN];
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _NET_BATMAN_ADV_TYPES_H_ */
|
|
@ -1,269 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2010 B.A.T.M.A.N. contributors:
|
|
||||||
*
|
|
||||||
* Andreas Langer
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of version 2 of the GNU General Public
|
|
||||||
* License as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
||||||
* 02110-1301, USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "main.h"
|
|
||||||
#include "unicast.h"
|
|
||||||
#include "send.h"
|
|
||||||
#include "soft-interface.h"
|
|
||||||
#include "hash.h"
|
|
||||||
#include "translation-table.h"
|
|
||||||
#include "routing.h"
|
|
||||||
#include "hard-interface.h"
|
|
||||||
|
|
||||||
|
|
||||||
struct sk_buff *merge_frag_packet(struct list_head *head,
|
|
||||||
struct frag_packet_list_entry *tfp,
|
|
||||||
struct sk_buff *skb)
|
|
||||||
{
|
|
||||||
struct unicast_frag_packet *up =
|
|
||||||
(struct unicast_frag_packet *)skb->data;
|
|
||||||
struct sk_buff *tmp_skb;
|
|
||||||
|
|
||||||
/* set skb to the first part and tmp_skb to the second part */
|
|
||||||
if (up->flags & UNI_FRAG_HEAD) {
|
|
||||||
tmp_skb = tfp->skb;
|
|
||||||
} else {
|
|
||||||
tmp_skb = skb;
|
|
||||||
skb = tfp->skb;
|
|
||||||
}
|
|
||||||
|
|
||||||
skb_pull(tmp_skb, sizeof(struct unicast_frag_packet));
|
|
||||||
if (pskb_expand_head(skb, 0, tmp_skb->len, GFP_ATOMIC) < 0) {
|
|
||||||
/* free buffered skb, skb will be freed later */
|
|
||||||
kfree_skb(tfp->skb);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* move free entry to end */
|
|
||||||
tfp->skb = NULL;
|
|
||||||
tfp->seqno = 0;
|
|
||||||
list_move_tail(&tfp->list, head);
|
|
||||||
|
|
||||||
memcpy(skb_put(skb, tmp_skb->len), tmp_skb->data, tmp_skb->len);
|
|
||||||
kfree_skb(tmp_skb);
|
|
||||||
return skb;
|
|
||||||
}
|
|
||||||
|
|
||||||
void create_frag_entry(struct list_head *head, struct sk_buff *skb)
|
|
||||||
{
|
|
||||||
struct frag_packet_list_entry *tfp;
|
|
||||||
struct unicast_frag_packet *up =
|
|
||||||
(struct unicast_frag_packet *)skb->data;
|
|
||||||
|
|
||||||
/* free and oldest packets stand at the end */
|
|
||||||
tfp = list_entry((head)->prev, typeof(*tfp), list);
|
|
||||||
kfree_skb(tfp->skb);
|
|
||||||
|
|
||||||
tfp->seqno = ntohs(up->seqno);
|
|
||||||
tfp->skb = skb;
|
|
||||||
list_move(&tfp->list, head);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int create_frag_buffer(struct list_head *head)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
struct frag_packet_list_entry *tfp;
|
|
||||||
|
|
||||||
for (i = 0; i < FRAG_BUFFER_SIZE; i++) {
|
|
||||||
tfp = kmalloc(sizeof(struct frag_packet_list_entry),
|
|
||||||
GFP_ATOMIC);
|
|
||||||
if (!tfp) {
|
|
||||||
frag_list_free(head);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
tfp->skb = NULL;
|
|
||||||
tfp->seqno = 0;
|
|
||||||
INIT_LIST_HEAD(&tfp->list);
|
|
||||||
list_add(&tfp->list, head);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct frag_packet_list_entry *search_frag_packet(struct list_head *head,
|
|
||||||
struct unicast_frag_packet *up)
|
|
||||||
{
|
|
||||||
struct frag_packet_list_entry *tfp;
|
|
||||||
struct unicast_frag_packet *tmp_up = NULL;
|
|
||||||
uint16_t search_seqno;
|
|
||||||
|
|
||||||
if (up->flags & UNI_FRAG_HEAD)
|
|
||||||
search_seqno = ntohs(up->seqno)+1;
|
|
||||||
else
|
|
||||||
search_seqno = ntohs(up->seqno)-1;
|
|
||||||
|
|
||||||
list_for_each_entry(tfp, head, list) {
|
|
||||||
|
|
||||||
if (!tfp->skb)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (tfp->seqno == ntohs(up->seqno))
|
|
||||||
goto mov_tail;
|
|
||||||
|
|
||||||
tmp_up = (struct unicast_frag_packet *)tfp->skb->data;
|
|
||||||
|
|
||||||
if (tfp->seqno == search_seqno) {
|
|
||||||
|
|
||||||
if ((tmp_up->flags & UNI_FRAG_HEAD) !=
|
|
||||||
(up->flags & UNI_FRAG_HEAD))
|
|
||||||
return tfp;
|
|
||||||
else
|
|
||||||
goto mov_tail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
mov_tail:
|
|
||||||
list_move_tail(&tfp->list, head);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void frag_list_free(struct list_head *head)
|
|
||||||
{
|
|
||||||
struct frag_packet_list_entry *pf, *tmp_pf;
|
|
||||||
|
|
||||||
if (!list_empty(head)) {
|
|
||||||
|
|
||||||
list_for_each_entry_safe(pf, tmp_pf, head, list) {
|
|
||||||
kfree_skb(pf->skb);
|
|
||||||
list_del(&pf->list);
|
|
||||||
kfree(pf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int unicast_send_frag_skb(struct sk_buff *skb, struct bat_priv *bat_priv,
|
|
||||||
struct batman_if *batman_if, uint8_t dstaddr[],
|
|
||||||
struct orig_node *orig_node)
|
|
||||||
{
|
|
||||||
struct unicast_frag_packet *ucast_frag1, *ucast_frag2;
|
|
||||||
int hdr_len = sizeof(struct unicast_frag_packet);
|
|
||||||
struct sk_buff *frag_skb;
|
|
||||||
int data_len = skb->len;
|
|
||||||
|
|
||||||
if (!bat_priv->primary_if)
|
|
||||||
goto dropped;
|
|
||||||
|
|
||||||
frag_skb = dev_alloc_skb(data_len - (data_len / 2) + hdr_len);
|
|
||||||
skb_split(skb, frag_skb, data_len / 2);
|
|
||||||
|
|
||||||
if (my_skb_head_push(frag_skb, hdr_len) < 0 ||
|
|
||||||
my_skb_head_push(skb, hdr_len) < 0)
|
|
||||||
goto drop_frag;
|
|
||||||
|
|
||||||
ucast_frag1 = (struct unicast_frag_packet *)skb->data;
|
|
||||||
ucast_frag2 = (struct unicast_frag_packet *)frag_skb->data;
|
|
||||||
|
|
||||||
ucast_frag1->version = COMPAT_VERSION;
|
|
||||||
ucast_frag1->packet_type = BAT_UNICAST_FRAG;
|
|
||||||
ucast_frag1->ttl = TTL;
|
|
||||||
memcpy(ucast_frag1->orig,
|
|
||||||
bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
|
|
||||||
memcpy(ucast_frag1->dest, orig_node->orig, ETH_ALEN);
|
|
||||||
|
|
||||||
memcpy(ucast_frag2, ucast_frag1, sizeof(struct unicast_frag_packet));
|
|
||||||
|
|
||||||
ucast_frag1->flags |= UNI_FRAG_HEAD;
|
|
||||||
ucast_frag2->flags &= ~UNI_FRAG_HEAD;
|
|
||||||
|
|
||||||
ucast_frag1->seqno = htons((uint16_t)atomic_inc_return(
|
|
||||||
&batman_if->frag_seqno));
|
|
||||||
|
|
||||||
ucast_frag2->seqno = htons((uint16_t)atomic_inc_return(
|
|
||||||
&batman_if->frag_seqno));
|
|
||||||
|
|
||||||
send_skb_packet(skb, batman_if, dstaddr);
|
|
||||||
send_skb_packet(frag_skb, batman_if, dstaddr);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
drop_frag:
|
|
||||||
kfree_skb(frag_skb);
|
|
||||||
dropped:
|
|
||||||
kfree_skb(skb);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv)
|
|
||||||
{
|
|
||||||
struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
|
|
||||||
struct unicast_packet *unicast_packet;
|
|
||||||
struct orig_node *orig_node;
|
|
||||||
struct batman_if *batman_if;
|
|
||||||
struct neigh_node *router;
|
|
||||||
int data_len = skb->len;
|
|
||||||
uint8_t dstaddr[6];
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&bat_priv->orig_hash_lock, flags);
|
|
||||||
|
|
||||||
/* get routing information */
|
|
||||||
orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash,
|
|
||||||
ethhdr->h_dest));
|
|
||||||
|
|
||||||
/* check for hna host */
|
|
||||||
if (!orig_node)
|
|
||||||
orig_node = transtable_search(bat_priv, ethhdr->h_dest);
|
|
||||||
|
|
||||||
router = find_router(bat_priv, orig_node, NULL);
|
|
||||||
|
|
||||||
if (!router)
|
|
||||||
goto unlock;
|
|
||||||
|
|
||||||
/* don't lock while sending the packets ... we therefore
|
|
||||||
* copy the required data before sending */
|
|
||||||
|
|
||||||
batman_if = router->if_incoming;
|
|
||||||
memcpy(dstaddr, router->addr, ETH_ALEN);
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
|
|
||||||
|
|
||||||
if (batman_if->if_status != IF_ACTIVE)
|
|
||||||
goto dropped;
|
|
||||||
|
|
||||||
if (atomic_read(&bat_priv->frag_enabled) &&
|
|
||||||
data_len + sizeof(struct unicast_packet) > batman_if->net_dev->mtu)
|
|
||||||
return unicast_send_frag_skb(skb, bat_priv, batman_if,
|
|
||||||
dstaddr, orig_node);
|
|
||||||
|
|
||||||
if (my_skb_head_push(skb, sizeof(struct unicast_packet)) < 0)
|
|
||||||
goto dropped;
|
|
||||||
|
|
||||||
unicast_packet = (struct unicast_packet *)skb->data;
|
|
||||||
|
|
||||||
unicast_packet->version = COMPAT_VERSION;
|
|
||||||
/* batman packet type: unicast */
|
|
||||||
unicast_packet->packet_type = BAT_UNICAST;
|
|
||||||
/* set unicast ttl */
|
|
||||||
unicast_packet->ttl = TTL;
|
|
||||||
/* copy the destination for faster routing */
|
|
||||||
memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN);
|
|
||||||
|
|
||||||
send_skb_packet(skb, batman_if, dstaddr);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
unlock:
|
|
||||||
spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
|
|
||||||
dropped:
|
|
||||||
kfree_skb(skb);
|
|
||||||
return 1;
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2010 B.A.T.M.A.N. contributors:
|
|
||||||
*
|
|
||||||
* Andreas Langer
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of version 2 of the GNU General Public
|
|
||||||
* License as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
||||||
* 02110-1301, USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _NET_BATMAN_ADV_UNICAST_H_
|
|
||||||
#define _NET_BATMAN_ADV_UNICAST_H_
|
|
||||||
|
|
||||||
#define FRAG_TIMEOUT 10000 /* purge frag list entrys after time in ms */
|
|
||||||
#define FRAG_BUFFER_SIZE 6 /* number of list elements in buffer */
|
|
||||||
|
|
||||||
struct sk_buff *merge_frag_packet(struct list_head *head,
|
|
||||||
struct frag_packet_list_entry *tfp,
|
|
||||||
struct sk_buff *skb);
|
|
||||||
|
|
||||||
void create_frag_entry(struct list_head *head, struct sk_buff *skb);
|
|
||||||
int create_frag_buffer(struct list_head *head);
|
|
||||||
struct frag_packet_list_entry *search_frag_packet(struct list_head *head,
|
|
||||||
struct unicast_frag_packet *up);
|
|
||||||
void frag_list_free(struct list_head *head);
|
|
||||||
int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv);
|
|
||||||
|
|
||||||
#endif /* _NET_BATMAN_ADV_UNICAST_H_ */
|
|
@ -1,895 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008-2010 B.A.T.M.A.N. contributors:
|
|
||||||
*
|
|
||||||
* Simon Wunderlich
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of version 2 of the GNU General Public
|
|
||||||
* License as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
||||||
* 02110-1301, USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "main.h"
|
|
||||||
#include "send.h"
|
|
||||||
#include "translation-table.h"
|
|
||||||
#include "vis.h"
|
|
||||||
#include "soft-interface.h"
|
|
||||||
#include "hard-interface.h"
|
|
||||||
#include "hash.h"
|
|
||||||
|
|
||||||
#define MAX_VIS_PACKET_SIZE 1000
|
|
||||||
|
|
||||||
/* Returns the smallest signed integer in two's complement with the sizeof x */
|
|
||||||
#define smallest_signed_int(x) (1u << (7u + 8u * (sizeof(x) - 1u)))
|
|
||||||
|
|
||||||
/* Checks if a sequence number x is a predecessor/successor of y.
|
|
||||||
* they handle overflows/underflows and can correctly check for a
|
|
||||||
* predecessor/successor unless the variable sequence number has grown by
|
|
||||||
* more then 2**(bitwidth(x)-1)-1.
|
|
||||||
* This means that for a uint8_t with the maximum value 255, it would think:
|
|
||||||
* - when adding nothing - it is neither a predecessor nor a successor
|
|
||||||
* - before adding more than 127 to the starting value - it is a predecessor,
|
|
||||||
* - when adding 128 - it is neither a predecessor nor a successor,
|
|
||||||
* - after adding more than 127 to the starting value - it is a successor */
|
|
||||||
#define seq_before(x, y) ({typeof(x) _dummy = (x - y); \
|
|
||||||
_dummy > smallest_signed_int(_dummy); })
|
|
||||||
#define seq_after(x, y) seq_before(y, x)
|
|
||||||
|
|
||||||
static void start_vis_timer(struct bat_priv *bat_priv);
|
|
||||||
|
|
||||||
/* free the info */
|
|
||||||
static void free_info(struct kref *ref)
|
|
||||||
{
|
|
||||||
struct vis_info *info = container_of(ref, struct vis_info, refcount);
|
|
||||||
struct bat_priv *bat_priv = info->bat_priv;
|
|
||||||
struct recvlist_node *entry, *tmp;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
list_del_init(&info->send_list);
|
|
||||||
spin_lock_irqsave(&bat_priv->vis_list_lock, flags);
|
|
||||||
list_for_each_entry_safe(entry, tmp, &info->recv_list, list) {
|
|
||||||
list_del(&entry->list);
|
|
||||||
kfree(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&bat_priv->vis_list_lock, flags);
|
|
||||||
kfree_skb(info->skb_packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compare two vis packets, used by the hashing algorithm */
|
|
||||||
static int vis_info_cmp(void *data1, void *data2)
|
|
||||||
{
|
|
||||||
struct vis_info *d1, *d2;
|
|
||||||
struct vis_packet *p1, *p2;
|
|
||||||
d1 = data1;
|
|
||||||
d2 = data2;
|
|
||||||
p1 = (struct vis_packet *)d1->skb_packet->data;
|
|
||||||
p2 = (struct vis_packet *)d2->skb_packet->data;
|
|
||||||
return compare_orig(p1->vis_orig, p2->vis_orig);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* hash function to choose an entry in a hash table of given size */
|
|
||||||
/* hash algorithm from http://en.wikipedia.org/wiki/Hash_table */
|
|
||||||
static int vis_info_choose(void *data, int size)
|
|
||||||
{
|
|
||||||
struct vis_info *vis_info = data;
|
|
||||||
struct vis_packet *packet;
|
|
||||||
unsigned char *key;
|
|
||||||
uint32_t hash = 0;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
packet = (struct vis_packet *)vis_info->skb_packet->data;
|
|
||||||
key = packet->vis_orig;
|
|
||||||
for (i = 0; i < ETH_ALEN; i++) {
|
|
||||||
hash += key[i];
|
|
||||||
hash += (hash << 10);
|
|
||||||
hash ^= (hash >> 6);
|
|
||||||
}
|
|
||||||
|
|
||||||
hash += (hash << 3);
|
|
||||||
hash ^= (hash >> 11);
|
|
||||||
hash += (hash << 15);
|
|
||||||
|
|
||||||
return hash % size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* insert interface to the list of interfaces of one originator, if it
|
|
||||||
* does not already exist in the list */
|
|
||||||
static void vis_data_insert_interface(const uint8_t *interface,
|
|
||||||
struct hlist_head *if_list,
|
|
||||||
bool primary)
|
|
||||||
{
|
|
||||||
struct if_list_entry *entry;
|
|
||||||
struct hlist_node *pos;
|
|
||||||
|
|
||||||
hlist_for_each_entry(entry, pos, if_list, list) {
|
|
||||||
if (compare_orig(entry->addr, (void *)interface))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* its a new address, add it to the list */
|
|
||||||
entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
|
|
||||||
if (!entry)
|
|
||||||
return;
|
|
||||||
memcpy(entry->addr, interface, ETH_ALEN);
|
|
||||||
entry->primary = primary;
|
|
||||||
hlist_add_head(&entry->list, if_list);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t vis_data_read_prim_sec(char *buff, struct hlist_head *if_list)
|
|
||||||
{
|
|
||||||
struct if_list_entry *entry;
|
|
||||||
struct hlist_node *pos;
|
|
||||||
size_t len = 0;
|
|
||||||
|
|
||||||
hlist_for_each_entry(entry, pos, if_list, list) {
|
|
||||||
if (entry->primary)
|
|
||||||
len += sprintf(buff + len, "PRIMARY, ");
|
|
||||||
else {
|
|
||||||
len += sprintf(buff + len, "SEC %pM, ", entry->addr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t vis_data_count_prim_sec(struct hlist_head *if_list)
|
|
||||||
{
|
|
||||||
struct if_list_entry *entry;
|
|
||||||
struct hlist_node *pos;
|
|
||||||
size_t count = 0;
|
|
||||||
|
|
||||||
hlist_for_each_entry(entry, pos, if_list, list) {
|
|
||||||
if (entry->primary)
|
|
||||||
count += 9;
|
|
||||||
else
|
|
||||||
count += 23;
|
|
||||||
}
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* read an entry */
|
|
||||||
static ssize_t vis_data_read_entry(char *buff, struct vis_info_entry *entry,
|
|
||||||
uint8_t *src, bool primary)
|
|
||||||
{
|
|
||||||
/* maximal length: max(4+17+2, 3+17+1+3+2) == 26 */
|
|
||||||
if (primary && entry->quality == 0)
|
|
||||||
return sprintf(buff, "HNA %pM, ", entry->dest);
|
|
||||||
else if (compare_orig(entry->src, src))
|
|
||||||
return sprintf(buff, "TQ %pM %d, ", entry->dest,
|
|
||||||
entry->quality);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int vis_seq_print_text(struct seq_file *seq, void *offset)
|
|
||||||
{
|
|
||||||
HASHIT(hashit);
|
|
||||||
HASHIT(hashit_count);
|
|
||||||
struct vis_info *info;
|
|
||||||
struct vis_packet *packet;
|
|
||||||
struct vis_info_entry *entries;
|
|
||||||
struct net_device *net_dev = (struct net_device *)seq->private;
|
|
||||||
struct bat_priv *bat_priv = netdev_priv(net_dev);
|
|
||||||
HLIST_HEAD(vis_if_list);
|
|
||||||
struct if_list_entry *entry;
|
|
||||||
struct hlist_node *pos, *n;
|
|
||||||
int i;
|
|
||||||
unsigned long flags;
|
|
||||||
int vis_server = atomic_read(&bat_priv->vis_mode);
|
|
||||||
size_t buff_pos, buf_size;
|
|
||||||
char *buff;
|
|
||||||
|
|
||||||
if ((!bat_priv->primary_if) ||
|
|
||||||
(vis_server == VIS_TYPE_CLIENT_UPDATE))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
buf_size = 1;
|
|
||||||
/* Estimate length */
|
|
||||||
spin_lock_irqsave(&bat_priv->vis_hash_lock, flags);
|
|
||||||
while (hash_iterate(bat_priv->vis_hash, &hashit_count)) {
|
|
||||||
info = hashit_count.bucket->data;
|
|
||||||
packet = (struct vis_packet *)info->skb_packet->data;
|
|
||||||
entries = (struct vis_info_entry *)
|
|
||||||
((char *)packet + sizeof(struct vis_packet));
|
|
||||||
|
|
||||||
for (i = 0; i < packet->entries; i++) {
|
|
||||||
if (entries[i].quality == 0)
|
|
||||||
continue;
|
|
||||||
vis_data_insert_interface(entries[i].src, &vis_if_list,
|
|
||||||
compare_orig(entries[i].src, packet->vis_orig));
|
|
||||||
}
|
|
||||||
|
|
||||||
hlist_for_each_entry(entry, pos, &vis_if_list, list) {
|
|
||||||
buf_size += 18 + 26 * packet->entries;
|
|
||||||
|
|
||||||
/* add primary/secondary records */
|
|
||||||
if (compare_orig(entry->addr, packet->vis_orig))
|
|
||||||
buf_size +=
|
|
||||||
vis_data_count_prim_sec(&vis_if_list);
|
|
||||||
|
|
||||||
buf_size += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
hlist_for_each_entry_safe(entry, pos, n, &vis_if_list, list) {
|
|
||||||
hlist_del(&entry->list);
|
|
||||||
kfree(entry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buff = kmalloc(buf_size, GFP_ATOMIC);
|
|
||||||
if (!buff) {
|
|
||||||
spin_unlock_irqrestore(&bat_priv->vis_hash_lock, flags);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
buff[0] = '\0';
|
|
||||||
buff_pos = 0;
|
|
||||||
|
|
||||||
while (hash_iterate(bat_priv->vis_hash, &hashit)) {
|
|
||||||
info = hashit.bucket->data;
|
|
||||||
packet = (struct vis_packet *)info->skb_packet->data;
|
|
||||||
entries = (struct vis_info_entry *)
|
|
||||||
((char *)packet + sizeof(struct vis_packet));
|
|
||||||
|
|
||||||
for (i = 0; i < packet->entries; i++) {
|
|
||||||
if (entries[i].quality == 0)
|
|
||||||
continue;
|
|
||||||
vis_data_insert_interface(entries[i].src, &vis_if_list,
|
|
||||||
compare_orig(entries[i].src, packet->vis_orig));
|
|
||||||
}
|
|
||||||
|
|
||||||
hlist_for_each_entry(entry, pos, &vis_if_list, list) {
|
|
||||||
buff_pos += sprintf(buff + buff_pos, "%pM,",
|
|
||||||
entry->addr);
|
|
||||||
|
|
||||||
for (i = 0; i < packet->entries; i++)
|
|
||||||
buff_pos += vis_data_read_entry(buff + buff_pos,
|
|
||||||
&entries[i],
|
|
||||||
entry->addr,
|
|
||||||
entry->primary);
|
|
||||||
|
|
||||||
/* add primary/secondary records */
|
|
||||||
if (compare_orig(entry->addr, packet->vis_orig))
|
|
||||||
buff_pos +=
|
|
||||||
vis_data_read_prim_sec(buff + buff_pos,
|
|
||||||
&vis_if_list);
|
|
||||||
|
|
||||||
buff_pos += sprintf(buff + buff_pos, "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
hlist_for_each_entry_safe(entry, pos, n, &vis_if_list, list) {
|
|
||||||
hlist_del(&entry->list);
|
|
||||||
kfree(entry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&bat_priv->vis_hash_lock, flags);
|
|
||||||
|
|
||||||
seq_printf(seq, "%s", buff);
|
|
||||||
kfree(buff);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* add the info packet to the send list, if it was not
|
|
||||||
* already linked in. */
|
|
||||||
static void send_list_add(struct bat_priv *bat_priv, struct vis_info *info)
|
|
||||||
{
|
|
||||||
if (list_empty(&info->send_list)) {
|
|
||||||
kref_get(&info->refcount);
|
|
||||||
list_add_tail(&info->send_list, &bat_priv->vis_send_list);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* delete the info packet from the send list, if it was
|
|
||||||
* linked in. */
|
|
||||||
static void send_list_del(struct vis_info *info)
|
|
||||||
{
|
|
||||||
if (!list_empty(&info->send_list)) {
|
|
||||||
list_del_init(&info->send_list);
|
|
||||||
kref_put(&info->refcount, free_info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* tries to add one entry to the receive list. */
|
|
||||||
static void recv_list_add(struct bat_priv *bat_priv,
|
|
||||||
struct list_head *recv_list, char *mac)
|
|
||||||
{
|
|
||||||
struct recvlist_node *entry;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
entry = kmalloc(sizeof(struct recvlist_node), GFP_ATOMIC);
|
|
||||||
if (!entry)
|
|
||||||
return;
|
|
||||||
|
|
||||||
memcpy(entry->mac, mac, ETH_ALEN);
|
|
||||||
spin_lock_irqsave(&bat_priv->vis_list_lock, flags);
|
|
||||||
list_add_tail(&entry->list, recv_list);
|
|
||||||
spin_unlock_irqrestore(&bat_priv->vis_list_lock, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* returns 1 if this mac is in the recv_list */
|
|
||||||
static int recv_list_is_in(struct bat_priv *bat_priv,
|
|
||||||
struct list_head *recv_list, char *mac)
|
|
||||||
{
|
|
||||||
struct recvlist_node *entry;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&bat_priv->vis_list_lock, flags);
|
|
||||||
list_for_each_entry(entry, recv_list, list) {
|
|
||||||
if (memcmp(entry->mac, mac, ETH_ALEN) == 0) {
|
|
||||||
spin_unlock_irqrestore(&bat_priv->vis_list_lock,
|
|
||||||
flags);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
spin_unlock_irqrestore(&bat_priv->vis_list_lock, flags);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* try to add the packet to the vis_hash. return NULL if invalid (e.g. too old,
|
|
||||||
* broken.. ). vis hash must be locked outside. is_new is set when the packet
|
|
||||||
* is newer than old entries in the hash. */
|
|
||||||
static struct vis_info *add_packet(struct bat_priv *bat_priv,
|
|
||||||
struct vis_packet *vis_packet,
|
|
||||||
int vis_info_len, int *is_new,
|
|
||||||
int make_broadcast)
|
|
||||||
{
|
|
||||||
struct vis_info *info, *old_info;
|
|
||||||
struct vis_packet *search_packet, *old_packet;
|
|
||||||
struct vis_info search_elem;
|
|
||||||
struct vis_packet *packet;
|
|
||||||
|
|
||||||
*is_new = 0;
|
|
||||||
/* sanity check */
|
|
||||||
if (!bat_priv->vis_hash)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* see if the packet is already in vis_hash */
|
|
||||||
search_elem.skb_packet = dev_alloc_skb(sizeof(struct vis_packet));
|
|
||||||
if (!search_elem.skb_packet)
|
|
||||||
return NULL;
|
|
||||||
search_packet = (struct vis_packet *)skb_put(search_elem.skb_packet,
|
|
||||||
sizeof(struct vis_packet));
|
|
||||||
|
|
||||||
memcpy(search_packet->vis_orig, vis_packet->vis_orig, ETH_ALEN);
|
|
||||||
old_info = hash_find(bat_priv->vis_hash, &search_elem);
|
|
||||||
kfree_skb(search_elem.skb_packet);
|
|
||||||
|
|
||||||
if (old_info != NULL) {
|
|
||||||
old_packet = (struct vis_packet *)old_info->skb_packet->data;
|
|
||||||
if (!seq_after(ntohl(vis_packet->seqno),
|
|
||||||
ntohl(old_packet->seqno))) {
|
|
||||||
if (old_packet->seqno == vis_packet->seqno) {
|
|
||||||
recv_list_add(bat_priv, &old_info->recv_list,
|
|
||||||
vis_packet->sender_orig);
|
|
||||||
return old_info;
|
|
||||||
} else {
|
|
||||||
/* newer packet is already in hash. */
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* remove old entry */
|
|
||||||
hash_remove(bat_priv->vis_hash, old_info);
|
|
||||||
send_list_del(old_info);
|
|
||||||
kref_put(&old_info->refcount, free_info);
|
|
||||||
}
|
|
||||||
|
|
||||||
info = kmalloc(sizeof(struct vis_info), GFP_ATOMIC);
|
|
||||||
if (!info)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
info->skb_packet = dev_alloc_skb(sizeof(struct vis_packet) +
|
|
||||||
vis_info_len + sizeof(struct ethhdr));
|
|
||||||
if (!info->skb_packet) {
|
|
||||||
kfree(info);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
skb_reserve(info->skb_packet, sizeof(struct ethhdr));
|
|
||||||
packet = (struct vis_packet *)skb_put(info->skb_packet,
|
|
||||||
sizeof(struct vis_packet) +
|
|
||||||
vis_info_len);
|
|
||||||
|
|
||||||
kref_init(&info->refcount);
|
|
||||||
INIT_LIST_HEAD(&info->send_list);
|
|
||||||
INIT_LIST_HEAD(&info->recv_list);
|
|
||||||
info->first_seen = jiffies;
|
|
||||||
info->bat_priv = bat_priv;
|
|
||||||
memcpy(packet, vis_packet, sizeof(struct vis_packet) + vis_info_len);
|
|
||||||
|
|
||||||
/* initialize and add new packet. */
|
|
||||||
*is_new = 1;
|
|
||||||
|
|
||||||
/* Make it a broadcast packet, if required */
|
|
||||||
if (make_broadcast)
|
|
||||||
memcpy(packet->target_orig, broadcast_addr, ETH_ALEN);
|
|
||||||
|
|
||||||
/* repair if entries is longer than packet. */
|
|
||||||
if (packet->entries * sizeof(struct vis_info_entry) > vis_info_len)
|
|
||||||
packet->entries = vis_info_len / sizeof(struct vis_info_entry);
|
|
||||||
|
|
||||||
recv_list_add(bat_priv, &info->recv_list, packet->sender_orig);
|
|
||||||
|
|
||||||
/* try to add it */
|
|
||||||
if (hash_add(bat_priv->vis_hash, info) < 0) {
|
|
||||||
/* did not work (for some reason) */
|
|
||||||
kref_put(&old_info->refcount, free_info);
|
|
||||||
info = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* handle the server sync packet, forward if needed. */
|
|
||||||
void receive_server_sync_packet(struct bat_priv *bat_priv,
|
|
||||||
struct vis_packet *vis_packet,
|
|
||||||
int vis_info_len)
|
|
||||||
{
|
|
||||||
struct vis_info *info;
|
|
||||||
int is_new, make_broadcast;
|
|
||||||
unsigned long flags;
|
|
||||||
int vis_server = atomic_read(&bat_priv->vis_mode);
|
|
||||||
|
|
||||||
make_broadcast = (vis_server == VIS_TYPE_SERVER_SYNC);
|
|
||||||
|
|
||||||
spin_lock_irqsave(&bat_priv->vis_hash_lock, flags);
|
|
||||||
info = add_packet(bat_priv, vis_packet, vis_info_len,
|
|
||||||
&is_new, make_broadcast);
|
|
||||||
if (!info)
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
/* only if we are server ourselves and packet is newer than the one in
|
|
||||||
* hash.*/
|
|
||||||
if (vis_server == VIS_TYPE_SERVER_SYNC && is_new)
|
|
||||||
send_list_add(bat_priv, info);
|
|
||||||
end:
|
|
||||||
spin_unlock_irqrestore(&bat_priv->vis_hash_lock, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* handle an incoming client update packet and schedule forward if needed. */
|
|
||||||
void receive_client_update_packet(struct bat_priv *bat_priv,
|
|
||||||
struct vis_packet *vis_packet,
|
|
||||||
int vis_info_len)
|
|
||||||
{
|
|
||||||
struct vis_info *info;
|
|
||||||
struct vis_packet *packet;
|
|
||||||
int is_new;
|
|
||||||
unsigned long flags;
|
|
||||||
int vis_server = atomic_read(&bat_priv->vis_mode);
|
|
||||||
int are_target = 0;
|
|
||||||
|
|
||||||
/* clients shall not broadcast. */
|
|
||||||
if (is_bcast(vis_packet->target_orig))
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Are we the target for this VIS packet? */
|
|
||||||
if (vis_server == VIS_TYPE_SERVER_SYNC &&
|
|
||||||
is_my_mac(vis_packet->target_orig))
|
|
||||||
are_target = 1;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&bat_priv->vis_hash_lock, flags);
|
|
||||||
info = add_packet(bat_priv, vis_packet, vis_info_len,
|
|
||||||
&is_new, are_target);
|
|
||||||
|
|
||||||
if (!info)
|
|
||||||
goto end;
|
|
||||||
/* note that outdated packets will be dropped at this point. */
|
|
||||||
|
|
||||||
packet = (struct vis_packet *)info->skb_packet->data;
|
|
||||||
|
|
||||||
/* send only if we're the target server or ... */
|
|
||||||
if (are_target && is_new) {
|
|
||||||
packet->vis_type = VIS_TYPE_SERVER_SYNC; /* upgrade! */
|
|
||||||
send_list_add(bat_priv, info);
|
|
||||||
|
|
||||||
/* ... we're not the recipient (and thus need to forward). */
|
|
||||||
} else if (!is_my_mac(packet->target_orig)) {
|
|
||||||
send_list_add(bat_priv, info);
|
|
||||||
}
|
|
||||||
|
|
||||||
end:
|
|
||||||
spin_unlock_irqrestore(&bat_priv->vis_hash_lock, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Walk the originators and find the VIS server with the best tq. Set the packet
|
|
||||||
* address to its address and return the best_tq.
|
|
||||||
*
|
|
||||||
* Must be called with the originator hash locked */
|
|
||||||
static int find_best_vis_server(struct bat_priv *bat_priv,
|
|
||||||
struct vis_info *info)
|
|
||||||
{
|
|
||||||
HASHIT(hashit);
|
|
||||||
struct orig_node *orig_node;
|
|
||||||
struct vis_packet *packet;
|
|
||||||
int best_tq = -1;
|
|
||||||
|
|
||||||
packet = (struct vis_packet *)info->skb_packet->data;
|
|
||||||
|
|
||||||
while (hash_iterate(bat_priv->orig_hash, &hashit)) {
|
|
||||||
orig_node = hashit.bucket->data;
|
|
||||||
if ((orig_node) && (orig_node->router) &&
|
|
||||||
(orig_node->flags & VIS_SERVER) &&
|
|
||||||
(orig_node->router->tq_avg > best_tq)) {
|
|
||||||
best_tq = orig_node->router->tq_avg;
|
|
||||||
memcpy(packet->target_orig, orig_node->orig, ETH_ALEN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return best_tq;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return true if the vis packet is full. */
|
|
||||||
static bool vis_packet_full(struct vis_info *info)
|
|
||||||
{
|
|
||||||
struct vis_packet *packet;
|
|
||||||
packet = (struct vis_packet *)info->skb_packet->data;
|
|
||||||
|
|
||||||
if (MAX_VIS_PACKET_SIZE / sizeof(struct vis_info_entry)
|
|
||||||
< packet->entries + 1)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* generates a packet of own vis data,
|
|
||||||
* returns 0 on success, -1 if no packet could be generated */
|
|
||||||
static int generate_vis_packet(struct bat_priv *bat_priv)
|
|
||||||
{
|
|
||||||
HASHIT(hashit_local);
|
|
||||||
HASHIT(hashit_global);
|
|
||||||
struct orig_node *orig_node;
|
|
||||||
struct vis_info *info = (struct vis_info *)bat_priv->my_vis_info;
|
|
||||||
struct vis_packet *packet = (struct vis_packet *)info->skb_packet->data;
|
|
||||||
struct vis_info_entry *entry;
|
|
||||||
struct hna_local_entry *hna_local_entry;
|
|
||||||
int best_tq = -1;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
info->first_seen = jiffies;
|
|
||||||
packet->vis_type = atomic_read(&bat_priv->vis_mode);
|
|
||||||
|
|
||||||
spin_lock_irqsave(&bat_priv->orig_hash_lock, flags);
|
|
||||||
memcpy(packet->target_orig, broadcast_addr, ETH_ALEN);
|
|
||||||
packet->ttl = TTL;
|
|
||||||
packet->seqno = htonl(ntohl(packet->seqno) + 1);
|
|
||||||
packet->entries = 0;
|
|
||||||
skb_trim(info->skb_packet, sizeof(struct vis_packet));
|
|
||||||
|
|
||||||
if (packet->vis_type == VIS_TYPE_CLIENT_UPDATE) {
|
|
||||||
best_tq = find_best_vis_server(bat_priv, info);
|
|
||||||
|
|
||||||
if (best_tq < 0) {
|
|
||||||
spin_unlock_irqrestore(&bat_priv->orig_hash_lock,
|
|
||||||
flags);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (hash_iterate(bat_priv->orig_hash, &hashit_global)) {
|
|
||||||
orig_node = hashit_global.bucket->data;
|
|
||||||
|
|
||||||
if (!orig_node->router)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!compare_orig(orig_node->router->addr, orig_node->orig))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (orig_node->router->if_incoming->if_status != IF_ACTIVE)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (orig_node->router->tq_avg < 1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* fill one entry into buffer. */
|
|
||||||
entry = (struct vis_info_entry *)
|
|
||||||
skb_put(info->skb_packet, sizeof(*entry));
|
|
||||||
memcpy(entry->src,
|
|
||||||
orig_node->router->if_incoming->net_dev->dev_addr,
|
|
||||||
ETH_ALEN);
|
|
||||||
memcpy(entry->dest, orig_node->orig, ETH_ALEN);
|
|
||||||
entry->quality = orig_node->router->tq_avg;
|
|
||||||
packet->entries++;
|
|
||||||
|
|
||||||
if (vis_packet_full(info)) {
|
|
||||||
spin_unlock_irqrestore(
|
|
||||||
&bat_priv->orig_hash_lock, flags);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
|
|
||||||
|
|
||||||
spin_lock_irqsave(&bat_priv->hna_lhash_lock, flags);
|
|
||||||
while (hash_iterate(bat_priv->hna_local_hash, &hashit_local)) {
|
|
||||||
hna_local_entry = hashit_local.bucket->data;
|
|
||||||
entry = (struct vis_info_entry *)skb_put(info->skb_packet,
|
|
||||||
sizeof(*entry));
|
|
||||||
memset(entry->src, 0, ETH_ALEN);
|
|
||||||
memcpy(entry->dest, hna_local_entry->addr, ETH_ALEN);
|
|
||||||
entry->quality = 0; /* 0 means HNA */
|
|
||||||
packet->entries++;
|
|
||||||
|
|
||||||
if (vis_packet_full(info)) {
|
|
||||||
spin_unlock_irqrestore(&bat_priv->hna_lhash_lock,
|
|
||||||
flags);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&bat_priv->hna_lhash_lock, flags);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* free old vis packets. Must be called with this vis_hash_lock
|
|
||||||
* held */
|
|
||||||
static void purge_vis_packets(struct bat_priv *bat_priv)
|
|
||||||
{
|
|
||||||
HASHIT(hashit);
|
|
||||||
struct vis_info *info;
|
|
||||||
|
|
||||||
while (hash_iterate(bat_priv->vis_hash, &hashit)) {
|
|
||||||
info = hashit.bucket->data;
|
|
||||||
|
|
||||||
/* never purge own data. */
|
|
||||||
if (info == bat_priv->my_vis_info)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (time_after(jiffies,
|
|
||||||
info->first_seen + VIS_TIMEOUT * HZ)) {
|
|
||||||
hash_remove_bucket(bat_priv->vis_hash, &hashit);
|
|
||||||
send_list_del(info);
|
|
||||||
kref_put(&info->refcount, free_info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void broadcast_vis_packet(struct bat_priv *bat_priv,
|
|
||||||
struct vis_info *info)
|
|
||||||
{
|
|
||||||
HASHIT(hashit);
|
|
||||||
struct orig_node *orig_node;
|
|
||||||
struct vis_packet *packet;
|
|
||||||
struct sk_buff *skb;
|
|
||||||
unsigned long flags;
|
|
||||||
struct batman_if *batman_if;
|
|
||||||
uint8_t dstaddr[ETH_ALEN];
|
|
||||||
|
|
||||||
|
|
||||||
spin_lock_irqsave(&bat_priv->orig_hash_lock, flags);
|
|
||||||
packet = (struct vis_packet *)info->skb_packet->data;
|
|
||||||
|
|
||||||
/* send to all routers in range. */
|
|
||||||
while (hash_iterate(bat_priv->orig_hash, &hashit)) {
|
|
||||||
orig_node = hashit.bucket->data;
|
|
||||||
|
|
||||||
/* if it's a vis server and reachable, send it. */
|
|
||||||
if ((!orig_node) || (!orig_node->router))
|
|
||||||
continue;
|
|
||||||
if (!(orig_node->flags & VIS_SERVER))
|
|
||||||
continue;
|
|
||||||
/* don't send it if we already received the packet from
|
|
||||||
* this node. */
|
|
||||||
if (recv_list_is_in(bat_priv, &info->recv_list,
|
|
||||||
orig_node->orig))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
memcpy(packet->target_orig, orig_node->orig, ETH_ALEN);
|
|
||||||
batman_if = orig_node->router->if_incoming;
|
|
||||||
memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
|
|
||||||
spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
|
|
||||||
|
|
||||||
skb = skb_clone(info->skb_packet, GFP_ATOMIC);
|
|
||||||
if (skb)
|
|
||||||
send_skb_packet(skb, batman_if, dstaddr);
|
|
||||||
|
|
||||||
spin_lock_irqsave(&bat_priv->orig_hash_lock, flags);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void unicast_vis_packet(struct bat_priv *bat_priv,
|
|
||||||
struct vis_info *info)
|
|
||||||
{
|
|
||||||
struct orig_node *orig_node;
|
|
||||||
struct sk_buff *skb;
|
|
||||||
struct vis_packet *packet;
|
|
||||||
unsigned long flags;
|
|
||||||
struct batman_if *batman_if;
|
|
||||||
uint8_t dstaddr[ETH_ALEN];
|
|
||||||
|
|
||||||
spin_lock_irqsave(&bat_priv->orig_hash_lock, flags);
|
|
||||||
packet = (struct vis_packet *)info->skb_packet->data;
|
|
||||||
orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash,
|
|
||||||
packet->target_orig));
|
|
||||||
|
|
||||||
if ((!orig_node) || (!orig_node->router))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
/* don't lock while sending the packets ... we therefore
|
|
||||||
* copy the required data before sending */
|
|
||||||
batman_if = orig_node->router->if_incoming;
|
|
||||||
memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
|
|
||||||
spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
|
|
||||||
|
|
||||||
skb = skb_clone(info->skb_packet, GFP_ATOMIC);
|
|
||||||
if (skb)
|
|
||||||
send_skb_packet(skb, batman_if, dstaddr);
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
out:
|
|
||||||
spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* only send one vis packet. called from send_vis_packets() */
|
|
||||||
static void send_vis_packet(struct bat_priv *bat_priv, struct vis_info *info)
|
|
||||||
{
|
|
||||||
struct vis_packet *packet;
|
|
||||||
|
|
||||||
packet = (struct vis_packet *)info->skb_packet->data;
|
|
||||||
if (packet->ttl < 2) {
|
|
||||||
pr_debug("Error - can't send vis packet: ttl exceeded\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(packet->sender_orig, bat_priv->primary_if->net_dev->dev_addr,
|
|
||||||
ETH_ALEN);
|
|
||||||
packet->ttl--;
|
|
||||||
|
|
||||||
if (is_bcast(packet->target_orig))
|
|
||||||
broadcast_vis_packet(bat_priv, info);
|
|
||||||
else
|
|
||||||
unicast_vis_packet(bat_priv, info);
|
|
||||||
packet->ttl++; /* restore TTL */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* called from timer; send (and maybe generate) vis packet. */
|
|
||||||
static void send_vis_packets(struct work_struct *work)
|
|
||||||
{
|
|
||||||
struct delayed_work *delayed_work =
|
|
||||||
container_of(work, struct delayed_work, work);
|
|
||||||
struct bat_priv *bat_priv =
|
|
||||||
container_of(delayed_work, struct bat_priv, vis_work);
|
|
||||||
struct vis_info *info, *temp;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&bat_priv->vis_hash_lock, flags);
|
|
||||||
purge_vis_packets(bat_priv);
|
|
||||||
|
|
||||||
if (generate_vis_packet(bat_priv) == 0) {
|
|
||||||
/* schedule if generation was successful */
|
|
||||||
send_list_add(bat_priv, bat_priv->my_vis_info);
|
|
||||||
}
|
|
||||||
|
|
||||||
list_for_each_entry_safe(info, temp, &bat_priv->vis_send_list,
|
|
||||||
send_list) {
|
|
||||||
|
|
||||||
kref_get(&info->refcount);
|
|
||||||
spin_unlock_irqrestore(&bat_priv->vis_hash_lock, flags);
|
|
||||||
|
|
||||||
if (bat_priv->primary_if)
|
|
||||||
send_vis_packet(bat_priv, info);
|
|
||||||
|
|
||||||
spin_lock_irqsave(&bat_priv->vis_hash_lock, flags);
|
|
||||||
send_list_del(info);
|
|
||||||
kref_put(&info->refcount, free_info);
|
|
||||||
}
|
|
||||||
spin_unlock_irqrestore(&bat_priv->vis_hash_lock, flags);
|
|
||||||
start_vis_timer(bat_priv);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* init the vis server. this may only be called when if_list is already
|
|
||||||
* initialized (e.g. bat0 is initialized, interfaces have been added) */
|
|
||||||
int vis_init(struct bat_priv *bat_priv)
|
|
||||||
{
|
|
||||||
struct vis_packet *packet;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
if (bat_priv->vis_hash)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&bat_priv->vis_hash_lock, flags);
|
|
||||||
|
|
||||||
bat_priv->vis_hash = hash_new(256, vis_info_cmp, vis_info_choose);
|
|
||||||
if (!bat_priv->vis_hash) {
|
|
||||||
pr_err("Can't initialize vis_hash\n");
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
bat_priv->my_vis_info = kmalloc(MAX_VIS_PACKET_SIZE, GFP_ATOMIC);
|
|
||||||
if (!bat_priv->my_vis_info) {
|
|
||||||
pr_err("Can't initialize vis packet\n");
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
bat_priv->my_vis_info->skb_packet = dev_alloc_skb(
|
|
||||||
sizeof(struct vis_packet) +
|
|
||||||
MAX_VIS_PACKET_SIZE +
|
|
||||||
sizeof(struct ethhdr));
|
|
||||||
if (!bat_priv->my_vis_info->skb_packet)
|
|
||||||
goto free_info;
|
|
||||||
|
|
||||||
skb_reserve(bat_priv->my_vis_info->skb_packet, sizeof(struct ethhdr));
|
|
||||||
packet = (struct vis_packet *)skb_put(
|
|
||||||
bat_priv->my_vis_info->skb_packet,
|
|
||||||
sizeof(struct vis_packet));
|
|
||||||
|
|
||||||
/* prefill the vis info */
|
|
||||||
bat_priv->my_vis_info->first_seen = jiffies -
|
|
||||||
msecs_to_jiffies(VIS_INTERVAL);
|
|
||||||
INIT_LIST_HEAD(&bat_priv->my_vis_info->recv_list);
|
|
||||||
INIT_LIST_HEAD(&bat_priv->my_vis_info->send_list);
|
|
||||||
kref_init(&bat_priv->my_vis_info->refcount);
|
|
||||||
bat_priv->my_vis_info->bat_priv = bat_priv;
|
|
||||||
packet->version = COMPAT_VERSION;
|
|
||||||
packet->packet_type = BAT_VIS;
|
|
||||||
packet->ttl = TTL;
|
|
||||||
packet->seqno = 0;
|
|
||||||
packet->entries = 0;
|
|
||||||
|
|
||||||
INIT_LIST_HEAD(&bat_priv->vis_send_list);
|
|
||||||
|
|
||||||
if (hash_add(bat_priv->vis_hash, bat_priv->my_vis_info) < 0) {
|
|
||||||
pr_err("Can't add own vis packet into hash\n");
|
|
||||||
/* not in hash, need to remove it manually. */
|
|
||||||
kref_put(&bat_priv->my_vis_info->refcount, free_info);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&bat_priv->vis_hash_lock, flags);
|
|
||||||
start_vis_timer(bat_priv);
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
free_info:
|
|
||||||
kfree(bat_priv->my_vis_info);
|
|
||||||
bat_priv->my_vis_info = NULL;
|
|
||||||
err:
|
|
||||||
spin_unlock_irqrestore(&bat_priv->vis_hash_lock, flags);
|
|
||||||
vis_quit(bat_priv);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Decrease the reference count on a hash item info */
|
|
||||||
static void free_info_ref(void *data, void *arg)
|
|
||||||
{
|
|
||||||
struct vis_info *info = data;
|
|
||||||
|
|
||||||
send_list_del(info);
|
|
||||||
kref_put(&info->refcount, free_info);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* shutdown vis-server */
|
|
||||||
void vis_quit(struct bat_priv *bat_priv)
|
|
||||||
{
|
|
||||||
unsigned long flags;
|
|
||||||
if (!bat_priv->vis_hash)
|
|
||||||
return;
|
|
||||||
|
|
||||||
cancel_delayed_work_sync(&bat_priv->vis_work);
|
|
||||||
|
|
||||||
spin_lock_irqsave(&bat_priv->vis_hash_lock, flags);
|
|
||||||
/* properly remove, kill timers ... */
|
|
||||||
hash_delete(bat_priv->vis_hash, free_info_ref, NULL);
|
|
||||||
bat_priv->vis_hash = NULL;
|
|
||||||
bat_priv->my_vis_info = NULL;
|
|
||||||
spin_unlock_irqrestore(&bat_priv->vis_hash_lock, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* schedule packets for (re)transmission */
|
|
||||||
static void start_vis_timer(struct bat_priv *bat_priv)
|
|
||||||
{
|
|
||||||
INIT_DELAYED_WORK(&bat_priv->vis_work, send_vis_packets);
|
|
||||||
queue_delayed_work(bat_event_workqueue, &bat_priv->vis_work,
|
|
||||||
msecs_to_jiffies(VIS_INTERVAL));
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008-2010 B.A.T.M.A.N. contributors:
|
|
||||||
*
|
|
||||||
* Simon Wunderlich, Marek Lindner
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of version 2 of the GNU General Public
|
|
||||||
* License as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
||||||
* 02110-1301, USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _NET_BATMAN_ADV_VIS_H_
|
|
||||||
#define _NET_BATMAN_ADV_VIS_H_
|
|
||||||
|
|
||||||
#define VIS_TIMEOUT 200 /* timeout of vis packets in seconds */
|
|
||||||
|
|
||||||
int vis_seq_print_text(struct seq_file *seq, void *offset);
|
|
||||||
void receive_server_sync_packet(struct bat_priv *bat_priv,
|
|
||||||
struct vis_packet *vis_packet,
|
|
||||||
int vis_info_len);
|
|
||||||
void receive_client_update_packet(struct bat_priv *bat_priv,
|
|
||||||
struct vis_packet *vis_packet,
|
|
||||||
int vis_info_len);
|
|
||||||
int vis_init(struct bat_priv *bat_priv);
|
|
||||||
void vis_quit(struct bat_priv *bat_priv);
|
|
||||||
|
|
||||||
#endif /* _NET_BATMAN_ADV_VIS_H_ */
|
|
@ -7,53 +7,6 @@
|
|||||||
#define MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES 256
|
#define MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES 256
|
||||||
#include "Debug.h"
|
#include "Debug.h"
|
||||||
|
|
||||||
typedef struct _LIST_ENTRY{
|
|
||||||
struct _LIST_ENTRY *next;
|
|
||||||
struct _LIST_ENTRY *prev;
|
|
||||||
} LIST_ENTRY, *PLIST_ENTRY;
|
|
||||||
|
|
||||||
typedef struct _BCM_LIST_ENTRY {
|
|
||||||
|
|
||||||
LIST_ENTRY Link;
|
|
||||||
|
|
||||||
} BCM_LIST_ENTRY, *PBCM_LIST_ENTRY;
|
|
||||||
|
|
||||||
typedef enum _RCB_STATUS
|
|
||||||
{
|
|
||||||
DRIVER_PROCESSED=1,
|
|
||||||
APPLICATION_PROCESSED
|
|
||||||
} RCB_STATUS, *PRCB_STATUS;
|
|
||||||
|
|
||||||
#define fFILLED 1
|
|
||||||
#define fEMPTY 0
|
|
||||||
|
|
||||||
struct _BCM_CB
|
|
||||||
{
|
|
||||||
// The network packet that this RCB is receiving
|
|
||||||
PVOID pv_packet;
|
|
||||||
// Describes the length of the packet .
|
|
||||||
UINT ui_packet_length;
|
|
||||||
// Pointer to the first buffer in the packet (only one buffer for Rx)
|
|
||||||
PUCHAR buffer;
|
|
||||||
atomic_t status;
|
|
||||||
UINT filled;
|
|
||||||
} __attribute__((packed));
|
|
||||||
typedef struct _BCM_CB BCM_CB,*PBCM_CB;
|
|
||||||
|
|
||||||
typedef BCM_CB BCM_RCB, *PBCM_RCB;
|
|
||||||
typedef BCM_CB BCM_TCB, *PBCM_TCB;
|
|
||||||
|
|
||||||
/* This is to be stored in the "pvOsDepData" of ADAPTER */
|
|
||||||
typedef struct LINUX_DEP_DATA
|
|
||||||
{
|
|
||||||
struct net_device *virtualdev; /* Our Interface (veth0) */
|
|
||||||
struct net_device *actualdev; /* True Interface (eth0) */
|
|
||||||
struct net_device_stats netstats; /* Net statistics */
|
|
||||||
struct fasync_struct *async_queue; /* For asynchronus notification */
|
|
||||||
|
|
||||||
} LINUX_DEP_DATA, *PLINUX_DEP_DATA;
|
|
||||||
|
|
||||||
|
|
||||||
struct _LEADER
|
struct _LEADER
|
||||||
{
|
{
|
||||||
USHORT Vcid;
|
USHORT Vcid;
|
||||||
@ -429,26 +382,28 @@ Driver adapter data structure
|
|||||||
struct _MINI_ADAPTER
|
struct _MINI_ADAPTER
|
||||||
{
|
{
|
||||||
struct _MINI_ADAPTER *next;
|
struct _MINI_ADAPTER *next;
|
||||||
PVOID pvOsDepData;
|
struct net_device *dev;
|
||||||
|
u32 msg_enable;
|
||||||
|
|
||||||
CHAR *caDsxReqResp;
|
CHAR *caDsxReqResp;
|
||||||
atomic_t ApplicationRunning;
|
atomic_t ApplicationRunning;
|
||||||
volatile INT CtrlQueueLen;
|
volatile INT CtrlQueueLen;
|
||||||
atomic_t AppCtrlQueueLen;
|
atomic_t AppCtrlQueueLen;
|
||||||
BOOLEAN AppCtrlQueueOverFlow;
|
BOOLEAN AppCtrlQueueOverFlow;
|
||||||
atomic_t CurrentApplicationCount;
|
atomic_t CurrentApplicationCount;
|
||||||
atomic_t RegisteredApplicationCount;
|
atomic_t RegisteredApplicationCount;
|
||||||
BOOLEAN TimerActive;
|
BOOLEAN LinkUpStatus;
|
||||||
ULONG StatisticsPointer;
|
BOOLEAN TimerActive;
|
||||||
|
u32 StatisticsPointer;
|
||||||
struct sk_buff *RxControlHead;
|
struct sk_buff *RxControlHead;
|
||||||
struct sk_buff *RxControlTail;
|
struct sk_buff *RxControlTail;
|
||||||
// spinlock_t RxControlQueuelock;
|
|
||||||
struct semaphore RxAppControlQueuelock;
|
struct semaphore RxAppControlQueuelock;
|
||||||
struct semaphore fw_download_sema;
|
struct semaphore fw_download_sema;
|
||||||
|
|
||||||
PPER_TARANG_DATA pTarangs;
|
PPER_TARANG_DATA pTarangs;
|
||||||
spinlock_t control_queue_lock;
|
spinlock_t control_queue_lock;
|
||||||
wait_queue_head_t process_read_wait_queue;
|
wait_queue_head_t process_read_wait_queue;
|
||||||
ULONG bcm_jiffies; /* Store Jiffies value */
|
|
||||||
|
|
||||||
// the pointer to the first packet we have queued in send
|
// the pointer to the first packet we have queued in send
|
||||||
// deserialized miniport support variables
|
// deserialized miniport support variables
|
||||||
@ -458,24 +413,15 @@ struct _MINI_ADAPTER
|
|||||||
// this to keep track of the Tx and Rx MailBox Registers.
|
// this to keep track of the Tx and Rx MailBox Registers.
|
||||||
atomic_t CurrNumFreeTxDesc;
|
atomic_t CurrNumFreeTxDesc;
|
||||||
// to keep track the no of byte recieved
|
// to keep track the no of byte recieved
|
||||||
atomic_t RxRollOverCount;
|
|
||||||
USHORT PrevNumRecvDescs;
|
USHORT PrevNumRecvDescs;
|
||||||
USHORT CurrNumRecvDescs;
|
USHORT CurrNumRecvDescs;
|
||||||
atomic_t GoodRxByteCount;
|
|
||||||
atomic_t GoodRxPktCount;
|
|
||||||
atomic_t BadRxByteCount;
|
|
||||||
atomic_t RxPacketDroppedCount;
|
|
||||||
atomic_t GoodTxByteCount;
|
|
||||||
atomic_t TxTotalPacketCount;
|
|
||||||
atomic_t TxDroppedPacketCount;
|
|
||||||
ULONG LinkUpStatus;
|
|
||||||
BOOLEAN TransferMode;
|
|
||||||
UINT u32TotalDSD;
|
UINT u32TotalDSD;
|
||||||
PacketInfo PackInfo[NO_OF_QUEUES];
|
PacketInfo PackInfo[NO_OF_QUEUES];
|
||||||
S_CLASSIFIER_RULE astClassifierTable[MAX_CLASSIFIERS];
|
S_CLASSIFIER_RULE astClassifierTable[MAX_CLASSIFIERS];
|
||||||
|
BOOLEAN TransferMode;
|
||||||
|
|
||||||
/*************** qos ******************/
|
/*************** qos ******************/
|
||||||
UINT bETHCSEnabled;
|
BOOLEAN bETHCSEnabled;
|
||||||
|
|
||||||
ULONG BEBucketSize;
|
ULONG BEBucketSize;
|
||||||
ULONG rtPSBucketSize;
|
ULONG rtPSBucketSize;
|
||||||
@ -483,7 +429,6 @@ struct _MINI_ADAPTER
|
|||||||
BOOLEAN AutoLinkUp;
|
BOOLEAN AutoLinkUp;
|
||||||
BOOLEAN AutoSyncup;
|
BOOLEAN AutoSyncup;
|
||||||
|
|
||||||
struct net_device *dev;
|
|
||||||
int major;
|
int major;
|
||||||
int minor;
|
int minor;
|
||||||
wait_queue_head_t tx_packet_wait_queue;
|
wait_queue_head_t tx_packet_wait_queue;
|
||||||
@ -491,8 +436,6 @@ struct _MINI_ADAPTER
|
|||||||
atomic_t process_waiting;
|
atomic_t process_waiting;
|
||||||
BOOLEAN fw_download_done;
|
BOOLEAN fw_download_done;
|
||||||
|
|
||||||
unsigned int ctrlpkt_present;
|
|
||||||
BOOLEAN packets_given_to_all;
|
|
||||||
char *txctlpacket[MAX_CNTRL_PKTS];
|
char *txctlpacket[MAX_CNTRL_PKTS];
|
||||||
atomic_t cntrlpktCnt ;
|
atomic_t cntrlpktCnt ;
|
||||||
atomic_t index_app_read_cntrlpkt;
|
atomic_t index_app_read_cntrlpkt;
|
||||||
@ -502,34 +445,30 @@ struct _MINI_ADAPTER
|
|||||||
struct semaphore rdmwrmsync;
|
struct semaphore rdmwrmsync;
|
||||||
|
|
||||||
STTARGETDSXBUFFER astTargetDsxBuffer[MAX_TARGET_DSX_BUFFERS];
|
STTARGETDSXBUFFER astTargetDsxBuffer[MAX_TARGET_DSX_BUFFERS];
|
||||||
ULONG ulFreeTargetBufferCnt;
|
ULONG ulFreeTargetBufferCnt;
|
||||||
ULONG ulCurrentTargetBuffer;
|
ULONG ulCurrentTargetBuffer;
|
||||||
ULONG ulTotalTargetBuffersAvailable;
|
ULONG ulTotalTargetBuffersAvailable;
|
||||||
unsigned int timeout;
|
|
||||||
int irq;
|
|
||||||
unsigned long chip_id;
|
unsigned long chip_id;
|
||||||
unsigned int bFlashBoot;
|
|
||||||
unsigned int if_up;
|
|
||||||
// spinlock_t sleeper_lock;
|
|
||||||
atomic_t rdm_wrm_access;
|
|
||||||
atomic_t tx_rx_access;
|
|
||||||
wait_queue_head_t lowpower_mode_wait_queue;
|
wait_queue_head_t lowpower_mode_wait_queue;
|
||||||
atomic_t bAbortedByHost;
|
|
||||||
BOOLEAN bBinDownloaded;
|
BOOLEAN bFlashBoot;
|
||||||
BOOLEAN bCfgDownloaded;
|
BOOLEAN bBinDownloaded;
|
||||||
USHORT usBestEffortQueueIndex;
|
BOOLEAN bCfgDownloaded;
|
||||||
BOOLEAN bSyncUpRequestSent;
|
BOOLEAN bSyncUpRequestSent;
|
||||||
// struct semaphore data_packet_queue_lock;
|
USHORT usBestEffortQueueIndex;
|
||||||
|
|
||||||
wait_queue_head_t ioctl_fw_dnld_wait_queue;
|
wait_queue_head_t ioctl_fw_dnld_wait_queue;
|
||||||
BOOLEAN waiting_to_fw_download_done;
|
BOOLEAN waiting_to_fw_download_done;
|
||||||
pid_t fw_download_process_pid;
|
pid_t fw_download_process_pid;
|
||||||
PSTARGETPARAMS pstargetparams;
|
PSTARGETPARAMS pstargetparams;
|
||||||
BOOLEAN device_removed;
|
BOOLEAN device_removed;
|
||||||
BOOLEAN DeviceAccess;
|
BOOLEAN DeviceAccess;
|
||||||
INT DDRSetting;
|
|
||||||
BOOLEAN bDDRInitDone;
|
|
||||||
ULONG ulPowerSaveMode;
|
|
||||||
BOOLEAN bIsAutoCorrectEnabled;
|
BOOLEAN bIsAutoCorrectEnabled;
|
||||||
|
BOOLEAN bDDRInitDone;
|
||||||
|
INT DDRSetting;
|
||||||
|
ULONG ulPowerSaveMode;
|
||||||
spinlock_t txtransmitlock;
|
spinlock_t txtransmitlock;
|
||||||
B_UINT8 txtransmit_running;
|
B_UINT8 txtransmit_running;
|
||||||
/* Thread for control packet handling */
|
/* Thread for control packet handling */
|
||||||
@ -567,13 +506,13 @@ struct _MINI_ADAPTER
|
|||||||
unsigned int usIdleModePattern;
|
unsigned int usIdleModePattern;
|
||||||
//BOOLEAN bTriedToWakeUpFromShutdown;
|
//BOOLEAN bTriedToWakeUpFromShutdown;
|
||||||
BOOLEAN bLinkDownRequested;
|
BOOLEAN bLinkDownRequested;
|
||||||
unsigned int check_for_hang;
|
|
||||||
int downloadDDR;
|
int downloadDDR;
|
||||||
PHS_DEVICE_EXTENSION stBCMPhsContext;
|
PHS_DEVICE_EXTENSION stBCMPhsContext;
|
||||||
S_HDR_SUPRESSION_CONTEXTINFO stPhsTxContextInfo;
|
S_HDR_SUPRESSION_CONTEXTINFO stPhsTxContextInfo;
|
||||||
uint8_t ucaPHSPktRestoreBuf[2048];
|
uint8_t ucaPHSPktRestoreBuf[2048];
|
||||||
uint8_t bPHSEnabled;
|
uint8_t bPHSEnabled;
|
||||||
int AutoFirmDld;
|
BOOLEAN AutoFirmDld;
|
||||||
BOOLEAN bMipsConfig;
|
BOOLEAN bMipsConfig;
|
||||||
BOOLEAN bDPLLConfig;
|
BOOLEAN bDPLLConfig;
|
||||||
UINT32 aTxPktSizeHist[MIBS_MAX_HIST_ENTRIES];
|
UINT32 aTxPktSizeHist[MIBS_MAX_HIST_ENTRIES];
|
||||||
@ -599,10 +538,9 @@ struct _MINI_ADAPTER
|
|||||||
|
|
||||||
|
|
||||||
struct semaphore NVMRdmWrmLock;
|
struct semaphore NVMRdmWrmLock;
|
||||||
BOOLEAN bNetworkInterfaceRegistered;
|
|
||||||
BOOLEAN bNetdeviceNotifierRegistered;
|
|
||||||
struct device *pstCreatedClassDevice;
|
struct device *pstCreatedClassDevice;
|
||||||
BOOLEAN bUsbClassDriverRegistered;
|
|
||||||
// BOOLEAN InterfaceUpStatus;
|
// BOOLEAN InterfaceUpStatus;
|
||||||
PFLASH2X_CS_INFO psFlash2xCSInfo;
|
PFLASH2X_CS_INFO psFlash2xCSInfo;
|
||||||
PFLASH_CS_INFO psFlashCSInfo ;
|
PFLASH_CS_INFO psFlashCSInfo ;
|
||||||
@ -630,17 +568,13 @@ struct _MINI_ADAPTER
|
|||||||
struct semaphore LowPowerModeSync;
|
struct semaphore LowPowerModeSync;
|
||||||
ULONG liDrainCalculated;
|
ULONG liDrainCalculated;
|
||||||
UINT gpioBitMap;
|
UINT gpioBitMap;
|
||||||
|
|
||||||
S_BCM_DEBUG_STATE stDebugState;
|
S_BCM_DEBUG_STATE stDebugState;
|
||||||
|
|
||||||
};
|
};
|
||||||
typedef struct _MINI_ADAPTER MINI_ADAPTER, *PMINI_ADAPTER;
|
typedef struct _MINI_ADAPTER MINI_ADAPTER, *PMINI_ADAPTER;
|
||||||
|
|
||||||
|
#define GET_BCM_ADAPTER(net_dev) netdev_priv(net_dev)
|
||||||
typedef struct _DEVICE_EXTENSION
|
|
||||||
{
|
|
||||||
PMINI_ADAPTER pAdapt;
|
|
||||||
}DEVICE_EXTENSION,*PDEVICE_EXTENSION;
|
|
||||||
|
|
||||||
|
|
||||||
struct _ETH_HEADER_STRUC {
|
struct _ETH_HEADER_STRUC {
|
||||||
UCHAR au8DestinationAddress[6];
|
UCHAR au8DestinationAddress[6];
|
||||||
@ -667,8 +601,8 @@ typedef LINK_REQUEST CONTROL_MESSAGE;
|
|||||||
|
|
||||||
typedef struct _DDR_SETTING
|
typedef struct _DDR_SETTING
|
||||||
{
|
{
|
||||||
ULONG ulRegAddress;
|
UINT ulRegAddress;
|
||||||
ULONG ulRegValue;
|
UINT ulRegValue;
|
||||||
}DDR_SETTING, *PDDR_SETTING;
|
}DDR_SETTING, *PDDR_SETTING;
|
||||||
typedef DDR_SETTING DDR_SET_NODE, *PDDR_SET_NODE;
|
typedef DDR_SETTING DDR_SET_NODE, *PDDR_SET_NODE;
|
||||||
INT
|
INT
|
||||||
|
@ -1,94 +0,0 @@
|
|||||||
|
|
||||||
/*
|
|
||||||
* File Name: Arp.c
|
|
||||||
* Abstract: This file contains the routines for handling ARP PACKETS
|
|
||||||
*/
|
|
||||||
#include "headers.h"
|
|
||||||
#define ARP_PKT_SIZE 60
|
|
||||||
|
|
||||||
/* =========================================================================
|
|
||||||
* Function - reply_to_arp_request()
|
|
||||||
*
|
|
||||||
* Description - When this host tries to broadcast ARP request packet through
|
|
||||||
* the virtual interface (veth0), reply directly to upper layer.
|
|
||||||
* This function allocates a new skb for ARP reply packet,
|
|
||||||
* fills in the fields of the packet and then sends it to
|
|
||||||
* upper layer.
|
|
||||||
*
|
|
||||||
* Parameters - skb: Pointer to sk_buff structure of the ARP request pkt.
|
|
||||||
*
|
|
||||||
* Returns - None
|
|
||||||
* =========================================================================*/
|
|
||||||
|
|
||||||
VOID
|
|
||||||
reply_to_arp_request(struct sk_buff *skb)
|
|
||||||
{
|
|
||||||
PMINI_ADAPTER Adapter;
|
|
||||||
struct ArpHeader *pArpHdr = NULL;
|
|
||||||
struct ethhdr *pethhdr = NULL;
|
|
||||||
UCHAR uiIPHdr[4];
|
|
||||||
/* Check for valid skb */
|
|
||||||
if(skb == NULL)
|
|
||||||
{
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Invalid skb: Cannot reply to ARP request\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Adapter = GET_BCM_ADAPTER(skb->dev);
|
|
||||||
/* Print the ARP Request Packet */
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, "ARP Packet Dump :");
|
|
||||||
BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, (PUCHAR)(skb->data), skb->len);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Extract the Ethernet Header and Arp Payload including Header
|
|
||||||
*/
|
|
||||||
pethhdr = (struct ethhdr *)skb->data;
|
|
||||||
pArpHdr = (struct ArpHeader *)(skb->data+ETH_HLEN);
|
|
||||||
|
|
||||||
if(Adapter->bETHCSEnabled)
|
|
||||||
{
|
|
||||||
if(memcmp(pethhdr->h_source, Adapter->dev->dev_addr, ETH_ALEN))
|
|
||||||
{
|
|
||||||
bcm_kfree_skb(skb);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the Ethernet Header First.
|
|
||||||
memcpy(pethhdr->h_dest, pethhdr->h_source, ETH_ALEN);
|
|
||||||
if(!memcmp(pethhdr->h_source, Adapter->dev->dev_addr, ETH_ALEN))
|
|
||||||
{
|
|
||||||
pethhdr->h_source[5]++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the reply to ARP Reply */
|
|
||||||
pArpHdr->arp.ar_op = ntohs(ARPOP_REPLY);
|
|
||||||
|
|
||||||
/* Set the HW Address properly */
|
|
||||||
memcpy(pArpHdr->ar_sha, pethhdr->h_source, ETH_ALEN);
|
|
||||||
memcpy(pArpHdr->ar_tha, pethhdr->h_dest, ETH_ALEN);
|
|
||||||
|
|
||||||
// Swapping the IP Adddress
|
|
||||||
memcpy(uiIPHdr,pArpHdr->ar_sip,4);
|
|
||||||
memcpy(pArpHdr->ar_sip,pArpHdr->ar_tip,4);
|
|
||||||
memcpy(pArpHdr->ar_tip,uiIPHdr,4);
|
|
||||||
|
|
||||||
/* Print the ARP Reply Packet */
|
|
||||||
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, "ARP REPLY PACKET: ");
|
|
||||||
|
|
||||||
/* Send the Packet to upper layer */
|
|
||||||
BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, (PUCHAR)(skb->data), skb->len);
|
|
||||||
|
|
||||||
skb->protocol = eth_type_trans(skb,skb->dev);
|
|
||||||
skb->pkt_type = PACKET_HOST;
|
|
||||||
|
|
||||||
// skb->mac.raw=skb->data+LEADER_SIZE;
|
|
||||||
skb_set_mac_header (skb, LEADER_SIZE);
|
|
||||||
netif_rx(skb);
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, "<=============\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
@ -1,264 +1,238 @@
|
|||||||
#include "headers.h"
|
#include "headers.h"
|
||||||
|
|
||||||
static INT bcm_notify_event(struct notifier_block *nb, ULONG event, PVOID dev)
|
|
||||||
{
|
|
||||||
struct net_device *ndev = (struct net_device*)dev;
|
|
||||||
PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
|
|
||||||
//PMINI_ADAPTER Adapter = (PMINI_ADAPTER)ndev->priv;
|
|
||||||
if(strncmp(ndev->name,gblpnetdev->name,5)==0)
|
|
||||||
{
|
|
||||||
switch(event)
|
|
||||||
{
|
|
||||||
case NETDEV_CHANGEADDR:
|
|
||||||
case NETDEV_GOING_DOWN:
|
|
||||||
/*ignore this */
|
|
||||||
break;
|
|
||||||
case NETDEV_DOWN:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NETDEV_UP:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NETDEV_REGISTER:
|
|
||||||
/* Increment the Reference Count for "veth0" */
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Register RefCount: %x\n",
|
|
||||||
netdev_refcnt_read(ndev));
|
|
||||||
dev_hold(ndev);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NETDEV_UNREGISTER:
|
|
||||||
/* Decrement the Reference Count for "veth0" */
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Unregister RefCnt: %x\n",
|
|
||||||
netdev_refcnt_read(ndev));
|
|
||||||
dev_put(ndev);
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return NOTIFY_DONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Notifier block to receive netdevice events */
|
|
||||||
static struct notifier_block bcm_notifier_block =
|
|
||||||
{
|
|
||||||
.notifier_call = bcm_notify_event,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct net_device *gblpnetdev;
|
struct net_device *gblpnetdev;
|
||||||
/***************************************************************************************/
|
|
||||||
/* proto-type of lower function */
|
|
||||||
#ifdef BCM_SHM_INTERFACE
|
|
||||||
const char *bcmVirtDeviceName="bcmeth";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static INT bcm_open(struct net_device *dev)
|
static INT bcm_open(struct net_device *dev)
|
||||||
{
|
{
|
||||||
PMINI_ADAPTER Adapter = NULL ; //(PMINI_ADAPTER)dev->priv;
|
PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev);
|
||||||
Adapter = GET_BCM_ADAPTER(dev);
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "======>");
|
if (Adapter->fw_download_done == FALSE) {
|
||||||
if(Adapter->fw_download_done==FALSE)
|
pr_notice(PFX "%s: link up failed (download in progress)\n",
|
||||||
return -EINVAL;
|
dev->name);
|
||||||
Adapter->if_up=1;
|
return -EBUSY;
|
||||||
if(Adapter->LinkUpStatus == 1){
|
|
||||||
if(netif_queue_stopped(Adapter->dev)){
|
|
||||||
netif_carrier_on(Adapter->dev);
|
|
||||||
netif_start_queue(Adapter->dev);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "<======");
|
if (netif_msg_ifup(Adapter))
|
||||||
return 0;
|
pr_info(PFX "%s: enabling interface\n", dev->name);
|
||||||
}
|
|
||||||
|
|
||||||
static INT bcm_close(struct net_device *dev)
|
if (Adapter->LinkUpStatus) {
|
||||||
{
|
if (netif_msg_link(Adapter))
|
||||||
PMINI_ADAPTER Adapter = NULL ;//gpadapter ;
|
pr_info(PFX "%s: link up\n", dev->name);
|
||||||
Adapter = GET_BCM_ADAPTER(dev);
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "=====>");
|
netif_carrier_on(Adapter->dev);
|
||||||
Adapter->if_up=0;
|
netif_start_queue(Adapter->dev);
|
||||||
if(!netif_queue_stopped(dev)) {
|
|
||||||
netif_carrier_off(dev);
|
|
||||||
netif_stop_queue(dev);
|
|
||||||
}
|
}
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"<=====");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct net_device_stats *bcm_get_stats(struct net_device *dev)
|
|
||||||
{
|
|
||||||
PLINUX_DEP_DATA pLinuxData=NULL;
|
|
||||||
PMINI_ADAPTER Adapter = NULL ;// gpadapter ;
|
|
||||||
Adapter = GET_BCM_ADAPTER(dev);
|
|
||||||
pLinuxData = (PLINUX_DEP_DATA)(Adapter->pvOsDepData);
|
|
||||||
|
|
||||||
//BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Dev = %p, pLinuxData = %p", dev, pLinuxData);
|
|
||||||
pLinuxData->netstats.rx_packets=atomic_read(&Adapter->RxRollOverCount)*64*1024+Adapter->PrevNumRecvDescs;
|
|
||||||
pLinuxData->netstats.rx_bytes=atomic_read(&Adapter->GoodRxByteCount)+atomic_read(&Adapter->BadRxByteCount);
|
|
||||||
pLinuxData->netstats.rx_dropped=atomic_read(&Adapter->RxPacketDroppedCount);
|
|
||||||
pLinuxData->netstats.rx_errors=atomic_read(&Adapter->RxPacketDroppedCount);
|
|
||||||
pLinuxData->netstats.rx_length_errors=0;
|
|
||||||
pLinuxData->netstats.rx_frame_errors=0;
|
|
||||||
pLinuxData->netstats.rx_crc_errors=0;
|
|
||||||
pLinuxData->netstats.tx_bytes=atomic_read(&Adapter->GoodTxByteCount);
|
|
||||||
pLinuxData->netstats.tx_packets=atomic_read(&Adapter->TxTotalPacketCount);
|
|
||||||
pLinuxData->netstats.tx_dropped=atomic_read(&Adapter->TxDroppedPacketCount);
|
|
||||||
|
|
||||||
return &(pLinuxData->netstats);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
@ingroup init_functions
|
|
||||||
Register other driver entry points with the kernel
|
|
||||||
*/
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
|
|
||||||
static struct net_device_ops bcmNetDevOps = {
|
|
||||||
.ndo_open = bcm_open,
|
|
||||||
.ndo_stop = bcm_close,
|
|
||||||
.ndo_get_stats = bcm_get_stats,
|
|
||||||
.ndo_start_xmit = bcm_transmit,
|
|
||||||
.ndo_change_mtu = eth_change_mtu,
|
|
||||||
.ndo_set_mac_address = eth_mac_addr,
|
|
||||||
.ndo_validate_addr = eth_validate_addr,
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int register_networkdev(PMINI_ADAPTER Adapter)
|
|
||||||
{
|
|
||||||
int result=0;
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
|
|
||||||
void **temp = NULL; /* actually we're *allocating* the device in alloc_etherdev */
|
|
||||||
#endif
|
|
||||||
Adapter->dev = alloc_etherdev(sizeof(PMINI_ADAPTER));
|
|
||||||
if(!Adapter->dev)
|
|
||||||
{
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "ERR: No Dev");
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
gblpnetdev = Adapter->dev;
|
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
|
|
||||||
Adapter->dev->priv = Adapter;
|
|
||||||
#else
|
|
||||||
temp = netdev_priv(Adapter->dev);
|
|
||||||
*temp = (void *)Adapter;
|
|
||||||
#endif
|
|
||||||
//BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "init adapterptr: %x %x\n", (UINT)Adapter, temp);
|
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
|
|
||||||
Adapter->dev->netdev_ops = &bcmNetDevOps;
|
|
||||||
#else
|
|
||||||
Adapter->dev->open = bcm_open;
|
|
||||||
Adapter->dev->stop = bcm_close;
|
|
||||||
Adapter->dev->get_stats = bcm_get_stats;
|
|
||||||
Adapter->dev->hard_start_xmit = bcm_transmit;
|
|
||||||
Adapter->dev->hard_header_len = ETH_HLEN + LEADER_SIZE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef BCM_SHM_INTERFACE
|
|
||||||
Adapter->dev->mtu = MTU_SIZE; /* 1400 Bytes */
|
|
||||||
/* Read the MAC Address from EEPROM */
|
|
||||||
ReadMacAddressFromNVM(Adapter);
|
|
||||||
|
|
||||||
|
|
||||||
/* Register the notifier block for getting netdevice events */
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Registering netdevice notifier\n");
|
|
||||||
result = register_netdevice_notifier(&bcm_notifier_block);
|
|
||||||
if(result)
|
|
||||||
{
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "BCM Notifier Block did not get registered");
|
|
||||||
Adapter->bNetdeviceNotifierRegistered = FALSE;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "BCM Notifier got Registered");
|
|
||||||
Adapter->bNetdeviceNotifierRegistered = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
Adapter->dev->mtu = CPE_MTU_SIZE;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
//for CPE - harcode the virtual mac address
|
|
||||||
Adapter->dev->dev_addr[0] = MII_WIMAX_MACADDRESS[0];
|
|
||||||
Adapter->dev->dev_addr[1] = MII_WIMAX_MACADDRESS[1];
|
|
||||||
Adapter->dev->dev_addr[2] = MII_WIMAX_MACADDRESS[2];
|
|
||||||
Adapter->dev->dev_addr[3] = MII_WIMAX_MACADDRESS[3];
|
|
||||||
Adapter->dev->dev_addr[4] = MII_WIMAX_MACADDRESS[4];
|
|
||||||
Adapter->dev->dev_addr[5] = MII_WIMAX_MACADDRESS[5];
|
|
||||||
#else
|
|
||||||
ReadMacAddressFromNVM(Adapter);
|
|
||||||
#endif
|
|
||||||
strcpy(Adapter->dev->name, bcmVirtDeviceName); //Copy the device name
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
result = register_netdev(Adapter->dev);
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
Adapter->bNetworkInterfaceRegistered = TRUE ;
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Beceem Network device name is %s!", Adapter->dev->name);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Network device can not be registered!");
|
|
||||||
Adapter->bNetworkInterfaceRegistered = FALSE ;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
Adapter->stDebugState.debug_level = DBG_LVL_CURR;
|
|
||||||
Adapter->stDebugState.type =(UINT)0xffffffff;
|
|
||||||
Adapter->stDebugState.subtype[DBG_TYPE_OTHERS] = 0xffffffff;
|
|
||||||
Adapter->stDebugState.subtype[DBG_TYPE_RX] = 0xffffffff;
|
|
||||||
Adapter->stDebugState.subtype[DBG_TYPE_TX] = 0xffffffff;
|
|
||||||
Adapter->stDebugState.subtype[DBG_TYPE_INITEXIT] = 0xffffffff;
|
|
||||||
|
|
||||||
printk("-------ps_adapter->stDebugState.type=%x\n",Adapter->stDebugState.type);
|
|
||||||
printk("-------ps_adapter->stDebugState.subtype[DBG_TYPE_OTHERS]=%x\n",Adapter->stDebugState.subtype[DBG_TYPE_OTHERS]);
|
|
||||||
printk("-------ps_adapter->stDebugState.subtype[DBG_TYPE_RX]=%x\n",Adapter->stDebugState.subtype[DBG_TYPE_RX]);
|
|
||||||
printk("-------ps_adapter->stDebugState.subtype[DBG_TYPE_TX]=%x\n",Adapter->stDebugState.subtype[DBG_TYPE_TX]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bcm_unregister_networkdev(PMINI_ADAPTER Adapter)
|
static INT bcm_close(struct net_device *dev)
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Unregistering the Net Dev...\n");
|
PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev);
|
||||||
if(Adapter->dev && !IS_ERR(Adapter->dev) && Adapter->bNetworkInterfaceRegistered)
|
|
||||||
unregister_netdev(Adapter->dev);
|
if (netif_msg_ifdown(Adapter))
|
||||||
/* Unregister the notifier block */
|
pr_info(PFX "%s: disabling interface\n", dev->name);
|
||||||
if(Adapter->bNetdeviceNotifierRegistered == TRUE)
|
|
||||||
{
|
netif_carrier_off(dev);
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Unregistering netdevice notifier\n");
|
netif_stop_queue(dev);
|
||||||
unregister_netdevice_notifier(&bcm_notifier_block);
|
|
||||||
}
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bcm_init(void)
|
static u16 bcm_select_queue(struct net_device *dev, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
|
return ClassifyPacket(netdev_priv(dev), skb);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************
|
||||||
|
* Function - bcm_transmit()
|
||||||
|
*
|
||||||
|
* Description - This is the main transmit function for our virtual
|
||||||
|
* interface(eth0). It handles the ARP packets. It
|
||||||
|
* clones this packet and then Queue it to a suitable
|
||||||
|
* Queue. Then calls the transmit_packet().
|
||||||
|
*
|
||||||
|
* Parameter - skb - Pointer to the socket buffer structure
|
||||||
|
* dev - Pointer to the virtual net device structure
|
||||||
|
*
|
||||||
|
*********************************************************************/
|
||||||
|
|
||||||
|
static netdev_tx_t bcm_transmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
|
{
|
||||||
|
PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev);
|
||||||
|
u16 qindex = skb_get_queue_mapping(skb);
|
||||||
|
|
||||||
|
|
||||||
|
if (Adapter->device_removed || !Adapter->LinkUpStatus)
|
||||||
|
goto drop;
|
||||||
|
|
||||||
|
if (Adapter->TransferMode != IP_PACKET_ONLY_MODE)
|
||||||
|
goto drop;
|
||||||
|
|
||||||
|
if (INVALID_QUEUE_INDEX == qindex)
|
||||||
|
goto drop;
|
||||||
|
|
||||||
|
if (Adapter->PackInfo[qindex].uiCurrentPacketsOnHost >=
|
||||||
|
SF_MAX_ALLOWED_PACKETS_TO_BACKUP)
|
||||||
|
return NETDEV_TX_BUSY;
|
||||||
|
|
||||||
|
/* Now Enqueue the packet */
|
||||||
|
if (netif_msg_tx_queued(Adapter))
|
||||||
|
pr_info(PFX "%s: enqueueing packet to queue %d\n",
|
||||||
|
dev->name, qindex);
|
||||||
|
|
||||||
|
spin_lock(&Adapter->PackInfo[qindex].SFQueueLock);
|
||||||
|
Adapter->PackInfo[qindex].uiCurrentBytesOnHost += skb->len;
|
||||||
|
Adapter->PackInfo[qindex].uiCurrentPacketsOnHost++;
|
||||||
|
|
||||||
|
*((B_UINT32 *) skb->cb + SKB_CB_LATENCY_OFFSET) = jiffies;
|
||||||
|
ENQUEUEPACKET(Adapter->PackInfo[qindex].FirstTxQueue,
|
||||||
|
Adapter->PackInfo[qindex].LastTxQueue, skb);
|
||||||
|
atomic_inc(&Adapter->TotalPacketCount);
|
||||||
|
spin_unlock(&Adapter->PackInfo[qindex].SFQueueLock);
|
||||||
|
|
||||||
|
/* FIXME - this is racy and incorrect, replace with work queue */
|
||||||
|
if (!atomic_read(&Adapter->TxPktAvail)) {
|
||||||
|
atomic_set(&Adapter->TxPktAvail, 1);
|
||||||
|
wake_up(&Adapter->tx_packet_wait_queue);
|
||||||
|
}
|
||||||
|
return NETDEV_TX_OK;
|
||||||
|
|
||||||
|
drop:
|
||||||
|
dev_kfree_skb(skb);
|
||||||
|
return NETDEV_TX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@ingroup init_functions
|
||||||
|
Register other driver entry points with the kernel
|
||||||
|
*/
|
||||||
|
static const struct net_device_ops bcmNetDevOps = {
|
||||||
|
.ndo_open = bcm_open,
|
||||||
|
.ndo_stop = bcm_close,
|
||||||
|
.ndo_start_xmit = bcm_transmit,
|
||||||
|
.ndo_change_mtu = eth_change_mtu,
|
||||||
|
.ndo_set_mac_address = eth_mac_addr,
|
||||||
|
.ndo_validate_addr = eth_validate_addr,
|
||||||
|
.ndo_select_queue = bcm_select_queue,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct device_type wimax_type = {
|
||||||
|
.name = "wimax",
|
||||||
|
};
|
||||||
|
|
||||||
|
static int bcm_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
|
||||||
|
{
|
||||||
|
cmd->supported = 0;
|
||||||
|
cmd->advertising = 0;
|
||||||
|
cmd->speed = SPEED_10000;
|
||||||
|
cmd->duplex = DUPLEX_FULL;
|
||||||
|
cmd->port = PORT_TP;
|
||||||
|
cmd->phy_address = 0;
|
||||||
|
cmd->transceiver = XCVR_INTERNAL;
|
||||||
|
cmd->autoneg = AUTONEG_DISABLE;
|
||||||
|
cmd->maxtxpkt = 0;
|
||||||
|
cmd->maxrxpkt = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bcm_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
|
||||||
|
{
|
||||||
|
PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev);
|
||||||
|
PS_INTERFACE_ADAPTER psIntfAdapter = Adapter->pvInterfaceAdapter;
|
||||||
|
struct usb_device *udev = interface_to_usbdev(psIntfAdapter->interface);
|
||||||
|
|
||||||
|
strcpy(info->driver, DRV_NAME);
|
||||||
|
strcpy(info->version, DRV_VERSION);
|
||||||
|
snprintf(info->fw_version, sizeof(info->fw_version), "%u.%u",
|
||||||
|
Adapter->uiFlashLayoutMajorVersion,
|
||||||
|
Adapter->uiFlashLayoutMinorVersion);
|
||||||
|
|
||||||
|
usb_make_path(udev, info->bus_info, sizeof(info->bus_info));
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 bcm_get_link(struct net_device *dev)
|
||||||
|
{
|
||||||
|
PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev);
|
||||||
|
|
||||||
|
return Adapter->LinkUpStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 bcm_get_msglevel (struct net_device *dev)
|
||||||
|
{
|
||||||
|
PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev);
|
||||||
|
|
||||||
|
return Adapter->msg_enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bcm_set_msglevel (struct net_device *dev, u32 level)
|
||||||
|
{
|
||||||
|
PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev);
|
||||||
|
|
||||||
|
Adapter->msg_enable = level;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct ethtool_ops bcm_ethtool_ops = {
|
||||||
|
.get_settings = bcm_get_settings,
|
||||||
|
.get_drvinfo = bcm_get_drvinfo,
|
||||||
|
.get_link = bcm_get_link,
|
||||||
|
.get_msglevel = bcm_get_msglevel,
|
||||||
|
.set_msglevel = bcm_set_msglevel,
|
||||||
|
};
|
||||||
|
|
||||||
|
int register_networkdev(PMINI_ADAPTER Adapter)
|
||||||
|
{
|
||||||
|
struct net_device *net = Adapter->dev;
|
||||||
|
PS_INTERFACE_ADAPTER IntfAdapter = Adapter->pvInterfaceAdapter;
|
||||||
|
struct usb_interface *udev = IntfAdapter->interface;
|
||||||
|
struct usb_device *xdev = IntfAdapter->udev;
|
||||||
|
|
||||||
int result;
|
int result;
|
||||||
result = InterfaceInitialize();
|
|
||||||
if(result)
|
net->netdev_ops = &bcmNetDevOps;
|
||||||
{
|
net->ethtool_ops = &bcm_ethtool_ops;
|
||||||
printk("Initialisation failed for usbbcm");
|
net->mtu = MTU_SIZE; /* 1400 Bytes */
|
||||||
|
net->tx_queue_len = TX_QLEN;
|
||||||
|
net->flags |= IFF_NOARP;
|
||||||
|
|
||||||
|
netif_carrier_off(net);
|
||||||
|
|
||||||
|
SET_NETDEV_DEVTYPE(net, &wimax_type);
|
||||||
|
|
||||||
|
/* Read the MAC Address from EEPROM */
|
||||||
|
result = ReadMacAddressFromNVM(Adapter);
|
||||||
|
if (result != STATUS_SUCCESS) {
|
||||||
|
dev_err(&udev->dev,
|
||||||
|
PFX "Error in Reading the mac Address: %d", result);
|
||||||
|
return -EIO;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
result = register_netdev(net);
|
||||||
printk("Initialised usbbcm");
|
if (result)
|
||||||
}
|
return result;
|
||||||
return result;
|
|
||||||
|
gblpnetdev = Adapter->dev;
|
||||||
|
|
||||||
|
if (netif_msg_probe(Adapter))
|
||||||
|
dev_info(&udev->dev, PFX "%s: register usb-%s-%s %pM\n",
|
||||||
|
net->name, xdev->bus->bus_name, xdev->devpath,
|
||||||
|
net->dev_addr);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void unregister_networkdev(PMINI_ADAPTER Adapter)
|
||||||
static void bcm_exit(void)
|
|
||||||
{
|
{
|
||||||
printk("%s %s Calling InterfaceExit\n",__FILE__, __FUNCTION__);
|
struct net_device *net = Adapter->dev;
|
||||||
InterfaceExit();
|
PS_INTERFACE_ADAPTER IntfAdapter = Adapter->pvInterfaceAdapter;
|
||||||
printk("%s %s InterfaceExit returned\n",__FILE__, __FUNCTION__);
|
struct usb_interface *udev = IntfAdapter->interface;
|
||||||
|
struct usb_device *xdev = IntfAdapter->udev;
|
||||||
|
|
||||||
|
if (netif_msg_probe(Adapter))
|
||||||
|
dev_info(&udev->dev, PFX "%s: unregister usb-%s%s\n",
|
||||||
|
net->name, xdev->bus->bus_name, xdev->devpath);
|
||||||
|
|
||||||
|
unregister_netdev(Adapter->dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
module_init(bcm_init);
|
|
||||||
module_exit(bcm_exit);
|
|
||||||
MODULE_LICENSE ("GPL");
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ typedef enum _E_CLASSIFIER_ACTION
|
|||||||
eDeleteClassifier
|
eDeleteClassifier
|
||||||
}E_CLASSIFIER_ACTION;
|
}E_CLASSIFIER_ACTION;
|
||||||
|
|
||||||
|
static ULONG GetNextTargetBufferLocation(PMINI_ADAPTER Adapter,B_UINT16 tid);
|
||||||
|
|
||||||
/************************************************************
|
/************************************************************
|
||||||
* Function - SearchSfid
|
* Function - SearchSfid
|
||||||
@ -28,7 +29,7 @@ typedef enum _E_CLASSIFIER_ACTION
|
|||||||
* Returns - Queue index for this SFID(If matched)
|
* Returns - Queue index for this SFID(If matched)
|
||||||
Else Invalid Queue Index(If Not matched)
|
Else Invalid Queue Index(If Not matched)
|
||||||
************************************************************/
|
************************************************************/
|
||||||
__inline INT SearchSfid(PMINI_ADAPTER Adapter,UINT uiSfid)
|
INT SearchSfid(PMINI_ADAPTER Adapter,UINT uiSfid)
|
||||||
{
|
{
|
||||||
INT iIndex=0;
|
INT iIndex=0;
|
||||||
for(iIndex=(NO_OF_QUEUES-1); iIndex>=0; iIndex--)
|
for(iIndex=(NO_OF_QUEUES-1); iIndex>=0; iIndex--)
|
||||||
@ -47,26 +48,16 @@ __inline INT SearchSfid(PMINI_ADAPTER Adapter,UINT uiSfid)
|
|||||||
* Returns - Queue index for the free SFID
|
* Returns - Queue index for the free SFID
|
||||||
* Else returns Invalid Index.
|
* Else returns Invalid Index.
|
||||||
****************************************************************/
|
****************************************************************/
|
||||||
__inline INT SearchFreeSfid(PMINI_ADAPTER Adapter)
|
static INT SearchFreeSfid(PMINI_ADAPTER Adapter)
|
||||||
{
|
{
|
||||||
UINT uiIndex=0;
|
UINT uiIndex=0;
|
||||||
|
|
||||||
for(uiIndex=0; uiIndex < (NO_OF_QUEUES-1); uiIndex++)
|
for(uiIndex=0; uiIndex < (NO_OF_QUEUES-1); uiIndex++)
|
||||||
if(Adapter->PackInfo[uiIndex].ulSFID==0)
|
if(Adapter->PackInfo[uiIndex].ulSFID==0)
|
||||||
return uiIndex;
|
return uiIndex;
|
||||||
return NO_OF_QUEUES+1;
|
return NO_OF_QUEUES+1;
|
||||||
}
|
}
|
||||||
|
|
||||||
__inline int SearchVcid(PMINI_ADAPTER Adapter,unsigned short usVcid)
|
|
||||||
{
|
|
||||||
int iIndex=0;
|
|
||||||
for(iIndex=(NO_OF_QUEUES-1);iIndex>=0;iIndex--)
|
|
||||||
if(Adapter->PackInfo[iIndex].usVCID_Value == usVcid)
|
|
||||||
return iIndex;
|
|
||||||
return NO_OF_QUEUES+1;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Function: SearchClsid
|
Function: SearchClsid
|
||||||
Description: This routinue would search Classifier having specified ClassifierID as input parameter
|
Description: This routinue would search Classifier having specified ClassifierID as input parameter
|
||||||
@ -76,7 +67,7 @@ Input parameters: PMINI_ADAPTER Adapter - Adapter Context
|
|||||||
Return: int :Classifier table index of matching entry
|
Return: int :Classifier table index of matching entry
|
||||||
*/
|
*/
|
||||||
|
|
||||||
__inline int SearchClsid(PMINI_ADAPTER Adapter,ULONG ulSFID,B_UINT16 uiClassifierID)
|
static int SearchClsid(PMINI_ADAPTER Adapter,ULONG ulSFID,B_UINT16 uiClassifierID)
|
||||||
{
|
{
|
||||||
unsigned int uiClassifierIndex = 0;
|
unsigned int uiClassifierIndex = 0;
|
||||||
for(uiClassifierIndex=0;uiClassifierIndex<MAX_CLASSIFIERS;uiClassifierIndex++)
|
for(uiClassifierIndex=0;uiClassifierIndex<MAX_CLASSIFIERS;uiClassifierIndex++)
|
||||||
@ -94,7 +85,7 @@ __inline int SearchClsid(PMINI_ADAPTER Adapter,ULONG ulSFID,B_UINT16 uiClassifi
|
|||||||
This routinue would search Free available Classifier entry in classifier table.
|
This routinue would search Free available Classifier entry in classifier table.
|
||||||
@return free Classifier Entry index in classifier table for specified SF
|
@return free Classifier Entry index in classifier table for specified SF
|
||||||
*/
|
*/
|
||||||
static __inline int SearchFreeClsid(PMINI_ADAPTER Adapter /**Adapter Context*/
|
static int SearchFreeClsid(PMINI_ADAPTER Adapter /**Adapter Context*/
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
unsigned int uiClassifierIndex = 0;
|
unsigned int uiClassifierIndex = 0;
|
||||||
@ -106,7 +97,7 @@ static __inline int SearchFreeClsid(PMINI_ADAPTER Adapter /**Adapter Context*/
|
|||||||
return MAX_CLASSIFIERS+1;
|
return MAX_CLASSIFIERS+1;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID deleteSFBySfid(PMINI_ADAPTER Adapter, UINT uiSearchRuleIndex)
|
static VOID deleteSFBySfid(PMINI_ADAPTER Adapter, UINT uiSearchRuleIndex)
|
||||||
{
|
{
|
||||||
//deleting all the packet held in the SF
|
//deleting all the packet held in the SF
|
||||||
flush_queue(Adapter,uiSearchRuleIndex);
|
flush_queue(Adapter,uiSearchRuleIndex);
|
||||||
@ -985,7 +976,7 @@ static VOID CopyToAdapter( register PMINI_ADAPTER Adapter, /**<Pointer to the A
|
|||||||
|
|
||||||
if(Adapter->PackInfo[uiSearchRuleIndex].pstSFIndication)
|
if(Adapter->PackInfo[uiSearchRuleIndex].pstSFIndication)
|
||||||
{
|
{
|
||||||
bcm_kfree(Adapter->PackInfo[uiSearchRuleIndex].pstSFIndication);
|
kfree(Adapter->PackInfo[uiSearchRuleIndex].pstSFIndication);
|
||||||
Adapter->PackInfo[uiSearchRuleIndex].pstSFIndication = NULL;
|
Adapter->PackInfo[uiSearchRuleIndex].pstSFIndication = NULL;
|
||||||
}
|
}
|
||||||
Adapter->PackInfo[uiSearchRuleIndex].pstSFIndication = pstAddIndication;
|
Adapter->PackInfo[uiSearchRuleIndex].pstSFIndication = pstAddIndication;
|
||||||
@ -1061,12 +1052,6 @@ static VOID DumpCmControlPacket(PVOID pvBuffer)
|
|||||||
pstAddIndication->sfAuthorizedSet.u32MaxTrafficBurst);
|
pstAddIndication->sfAuthorizedSet.u32MaxTrafficBurst);
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MinReservedTrafficRate : 0x%X",
|
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MinReservedTrafficRate : 0x%X",
|
||||||
pstAddIndication->sfAuthorizedSet.u32MinReservedTrafficRate);
|
pstAddIndication->sfAuthorizedSet.u32MinReservedTrafficRate);
|
||||||
#if 0
|
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MinimumTolerableTrafficRate : 0x%X",
|
|
||||||
pstAddIndication->sfAuthorizedSet.u32MinimumTolerableTrafficRate);
|
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32RequesttransmissionPolicy : 0x%X",
|
|
||||||
pstAddIndication->sfAuthorizedSet.u32RequesttransmissionPolicy);
|
|
||||||
#endif
|
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParamLength : 0x%X",
|
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParamLength : 0x%X",
|
||||||
pstAddIndication->sfAuthorizedSet.u8VendorSpecificQoSParamLength);
|
pstAddIndication->sfAuthorizedSet.u8VendorSpecificQoSParamLength);
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParam : 0x%X",
|
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParam : 0x%X",
|
||||||
@ -1114,13 +1099,6 @@ static VOID DumpCmControlPacket(PVOID pvBuffer)
|
|||||||
pstAddIndication->sfAuthorizedSet.u8PagingPreference);
|
pstAddIndication->sfAuthorizedSet.u8PagingPreference);
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16UnsolicitedPollingInterval : 0x%X",
|
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16UnsolicitedPollingInterval : 0x%X",
|
||||||
pstAddIndication->sfAuthorizedSet.u16UnsolicitedPollingInterval);
|
pstAddIndication->sfAuthorizedSet.u16UnsolicitedPollingInterval);
|
||||||
#if 0
|
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "MBSZoneIdentifierassignmentLength : 0x%X",
|
|
||||||
pstAddIndication->sfAuthorizedSet.MBSZoneIdentifierassignmentLength);
|
|
||||||
for(uiLoopIndex=0; uiLoopIndex < MAX_STRING_LEN; uiLoopIndex++)
|
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "MBSZoneIdentifierassignment : 0x%X",
|
|
||||||
pstAddIndication->sfAuthorizedSet.MBSZoneIdentifierassignment[uiLoopIndex]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "sfAuthorizedSet.u8HARQChannelMapping %x %x %x ",
|
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "sfAuthorizedSet.u8HARQChannelMapping %x %x %x ",
|
||||||
*(unsigned int*)pstAddIndication->sfAuthorizedSet.u8HARQChannelMapping,
|
*(unsigned int*)pstAddIndication->sfAuthorizedSet.u8HARQChannelMapping,
|
||||||
@ -1158,11 +1136,6 @@ static VOID DumpCmControlPacket(PVOID pvBuffer)
|
|||||||
psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0],
|
psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0],
|
||||||
psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1],
|
psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1],
|
||||||
psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2]);
|
psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2]);
|
||||||
#if 0
|
|
||||||
|
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "u8ProtocolLength :0x%X ",
|
|
||||||
psfCSType->cCPacketClassificationRule.u8ProtocolLength);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for(uiLoopIndex=0; uiLoopIndex < 1; uiLoopIndex++)
|
for(uiLoopIndex=0; uiLoopIndex < 1; uiLoopIndex++)
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Protocol : 0x%02X ",
|
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Protocol : 0x%02X ",
|
||||||
@ -1278,14 +1251,6 @@ static VOID DumpCmControlPacket(PVOID pvBuffer)
|
|||||||
pstAddIndication->sfAdmittedSet.u8QosParamSet);
|
pstAddIndication->sfAdmittedSet.u8QosParamSet);
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficPriority : 0x%02X",
|
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficPriority : 0x%02X",
|
||||||
pstAddIndication->sfAdmittedSet.u8TrafficPriority);
|
pstAddIndication->sfAdmittedSet.u8TrafficPriority);
|
||||||
#if 0
|
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "u32MaxSustainedTrafficRate : 0x%02X",
|
|
||||||
ntohl(pstAddIndication->sfAdmittedSet.u32MaxSustainedTrafficRate));
|
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "u32MinimumTolerableTrafficRate : 0x%X",
|
|
||||||
pstAddIndication->sfAdmittedSet.u32MinimumTolerableTrafficRate);
|
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "u32RequesttransmissionPolicy : 0x%X",
|
|
||||||
pstAddIndication->sfAdmittedSet.u32RequesttransmissionPolicy);
|
|
||||||
#endif
|
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaxTrafficBurst : 0x%X",
|
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaxTrafficBurst : 0x%X",
|
||||||
pstAddIndication->sfAdmittedSet.u32MaxTrafficBurst);
|
pstAddIndication->sfAdmittedSet.u32MaxTrafficBurst);
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MinReservedTrafficRate : 0x%X",
|
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MinReservedTrafficRate : 0x%X",
|
||||||
@ -1339,13 +1304,6 @@ static VOID DumpCmControlPacket(PVOID pvBuffer)
|
|||||||
pstAddIndication->sfAdmittedSet.u16TimeBase);
|
pstAddIndication->sfAdmittedSet.u16TimeBase);
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8PagingPreference : 0x%X",
|
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8PagingPreference : 0x%X",
|
||||||
pstAddIndication->sfAdmittedSet.u8PagingPreference);
|
pstAddIndication->sfAdmittedSet.u8PagingPreference);
|
||||||
#if 0
|
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "MBSZoneIdentifierassignmentLength : 0x%X",
|
|
||||||
pstAddIndication->sfAdmittedSet.MBSZoneIdentifierassignmentLength);
|
|
||||||
for(uiLoopIndex=0; uiLoopIndex < MAX_STRING_LEN; uiLoopIndex++)
|
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "MBSZoneIdentifierassignment : 0x%X",
|
|
||||||
pstAddIndication->sfAdmittedSet.MBSZoneIdentifierassignment[uiLoopIndex]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficIndicationPreference : 0x%02X",
|
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficIndicationPreference : 0x%02X",
|
||||||
@ -1378,11 +1336,6 @@ static VOID DumpCmControlPacket(PVOID pvBuffer)
|
|||||||
psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0],
|
psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0],
|
||||||
psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1],
|
psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1],
|
||||||
psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2]);
|
psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2]);
|
||||||
#if 0
|
|
||||||
|
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolLength :0x%02X ",
|
|
||||||
psfCSType->cCPacketClassificationRule.u8ProtocolLength);
|
|
||||||
#endif
|
|
||||||
for(uiLoopIndex=0; uiLoopIndex < 1; uiLoopIndex++)
|
for(uiLoopIndex=0; uiLoopIndex < 1; uiLoopIndex++)
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Protocol: 0x%02X ",
|
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Protocol: 0x%02X ",
|
||||||
psfCSType->cCPacketClassificationRule.u8Protocol);
|
psfCSType->cCPacketClassificationRule.u8Protocol);
|
||||||
@ -1497,20 +1450,10 @@ static VOID DumpCmControlPacket(PVOID pvBuffer)
|
|||||||
pstAddIndication->sfActiveSet.u8QosParamSet);
|
pstAddIndication->sfActiveSet.u8QosParamSet);
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficPriority : 0x%02X",
|
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficPriority : 0x%02X",
|
||||||
pstAddIndication->sfActiveSet.u8TrafficPriority);
|
pstAddIndication->sfActiveSet.u8TrafficPriority);
|
||||||
#if 0
|
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "u32MaxSustainedTrafficRate : 0x%02X",
|
|
||||||
ntohl(pstAddIndication->sfActiveSet.u32MaxSustainedTrafficRate));
|
|
||||||
#endif
|
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaxTrafficBurst : 0x%X",
|
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaxTrafficBurst : 0x%X",
|
||||||
pstAddIndication->sfActiveSet.u32MaxTrafficBurst);
|
pstAddIndication->sfActiveSet.u32MaxTrafficBurst);
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MinReservedTrafficRate : 0x%X",
|
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MinReservedTrafficRate : 0x%X",
|
||||||
pstAddIndication->sfActiveSet.u32MinReservedTrafficRate);
|
pstAddIndication->sfActiveSet.u32MinReservedTrafficRate);
|
||||||
#if 0
|
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "u32MinimumTolerableTrafficRate : 0x%X",
|
|
||||||
pstAddIndication->sfActiveSet.u32MinimumTolerableTrafficRate);
|
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "u32RequesttransmissionPolicy : 0x%X",
|
|
||||||
pstAddIndication->sfActiveSet.u32RequesttransmissionPolicy);
|
|
||||||
#endif
|
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParamLength : 0x%02X",
|
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParamLength : 0x%02X",
|
||||||
pstAddIndication->sfActiveSet.u8VendorSpecificQoSParamLength);
|
pstAddIndication->sfActiveSet.u8VendorSpecificQoSParamLength);
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParam : 0x%02X",
|
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParam : 0x%02X",
|
||||||
@ -1558,13 +1501,6 @@ static VOID DumpCmControlPacket(PVOID pvBuffer)
|
|||||||
pstAddIndication->sfActiveSet.u16TimeBase);
|
pstAddIndication->sfActiveSet.u16TimeBase);
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8PagingPreference : 0x%X",
|
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8PagingPreference : 0x%X",
|
||||||
pstAddIndication->sfActiveSet.u8PagingPreference);
|
pstAddIndication->sfActiveSet.u8PagingPreference);
|
||||||
#if 0
|
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " MBSZoneIdentifierassignmentLength : 0x%X",
|
|
||||||
pstAddIndication->sfActiveSet.MBSZoneIdentifierassignmentLength);
|
|
||||||
for(uiLoopIndex=0; uiLoopIndex < MAX_STRING_LEN; uiLoopIndex++)
|
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " MBSZoneIdentifierassignment : 0x%X",
|
|
||||||
pstAddIndication->sfActiveSet.MBSZoneIdentifierassignment[uiLoopIndex]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8TrafficIndicationPreference : 0x%X",
|
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8TrafficIndicationPreference : 0x%X",
|
||||||
@ -1597,11 +1533,6 @@ static VOID DumpCmControlPacket(PVOID pvBuffer)
|
|||||||
psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0],
|
psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0],
|
||||||
psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1],
|
psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1],
|
||||||
psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2]);
|
psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2]);
|
||||||
#if 0
|
|
||||||
|
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " u8ProtocolLength :0x%X ",
|
|
||||||
psfCSType->cCPacketClassificationRule.u8ProtocolLength);
|
|
||||||
#endif
|
|
||||||
for(uiLoopIndex=0; uiLoopIndex < 1; uiLoopIndex++)
|
for(uiLoopIndex=0; uiLoopIndex < 1; uiLoopIndex++)
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8Protocol : 0x%X ",
|
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8Protocol : 0x%X ",
|
||||||
psfCSType->cCPacketClassificationRule.u8Protocol);
|
psfCSType->cCPacketClassificationRule.u8Protocol);
|
||||||
@ -1706,12 +1637,8 @@ static inline ULONG RestoreSFParam(PMINI_ADAPTER Adapter, ULONG ulAddrSFParamSet
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ulAddrSFParamSet = ntohl(ulAddrSFParamSet);
|
ulAddrSFParamSet = ntohl(ulAddrSFParamSet);
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " RestoreSFParam: Total Words of DSX Message To Read: 0x%zx From Target At : 0x%lx ",
|
|
||||||
nBytesToRead/sizeof(ULONG),ulAddrSFParamSet);
|
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "sizeof(stServiceFlowParamSI) = %zx", sizeof(stServiceFlowParamSI));
|
|
||||||
|
|
||||||
//Read out the SF Param Set At the indicated Location
|
//Read out the SF Param Set At the indicated Location
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "nBytesToRead = %x", nBytesToRead);
|
|
||||||
if(rdm(Adapter, ulAddrSFParamSet, (PUCHAR)pucDestBuffer, nBytesToRead) < 0)
|
if(rdm(Adapter, ulAddrSFParamSet, (PUCHAR)pucDestBuffer, nBytesToRead) < 0)
|
||||||
return STATUS_FAILURE;
|
return STATUS_FAILURE;
|
||||||
|
|
||||||
@ -1719,23 +1646,20 @@ static inline ULONG RestoreSFParam(PMINI_ADAPTER Adapter, ULONG ulAddrSFParamSet
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static __inline ULONG StoreSFParam(PMINI_ADAPTER Adapter,PUCHAR pucSrcBuffer,ULONG ulAddrSFParamSet)
|
static ULONG StoreSFParam(PMINI_ADAPTER Adapter,PUCHAR pucSrcBuffer,ULONG ulAddrSFParamSet)
|
||||||
{
|
{
|
||||||
UINT nBytesToWrite = sizeof(stServiceFlowParamSI);
|
UINT nBytesToWrite = sizeof(stServiceFlowParamSI);
|
||||||
UINT uiRetVal =0;
|
int ret = 0;
|
||||||
|
|
||||||
if(ulAddrSFParamSet == 0 || NULL == pucSrcBuffer)
|
if(ulAddrSFParamSet == 0 || NULL == pucSrcBuffer)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " StoreSFParam: Total Words of DSX Message To Write: 0x%zX To Target At : 0x%lX ",(nBytesToWrite/sizeof(ULONG)),ulAddrSFParamSet);
|
|
||||||
|
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "WRM with %x bytes",nBytesToWrite);
|
ret = wrm(Adapter, ulAddrSFParamSet, (u8 *)pucSrcBuffer, nBytesToWrite);
|
||||||
|
if (ret < 0) {
|
||||||
uiRetVal = wrm(Adapter,ulAddrSFParamSet,(PUCHAR)pucSrcBuffer, nBytesToWrite);
|
|
||||||
if(uiRetVal < 0) {
|
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "%s:%d WRM failed",__FUNCTION__, __LINE__);
|
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "%s:%d WRM failed",__FUNCTION__, __LINE__);
|
||||||
return uiRetVal;
|
return ret;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -1778,7 +1702,7 @@ ULONG StoreCmControlResponseMessage(PMINI_ADAPTER Adapter,PVOID pvBuffer,UINT *p
|
|||||||
}
|
}
|
||||||
// For DSA_REQ, only upto "psfAuthorizedSet" parameter should be accessed by driver!
|
// For DSA_REQ, only upto "psfAuthorizedSet" parameter should be accessed by driver!
|
||||||
|
|
||||||
pstAddIndication=(stLocalSFAddIndication *)kmalloc(sizeof(*pstAddIndication), GFP_KERNEL);
|
pstAddIndication=kmalloc(sizeof(*pstAddIndication), GFP_KERNEL);
|
||||||
if(NULL==pstAddIndication)
|
if(NULL==pstAddIndication)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -1844,7 +1768,7 @@ ULONG StoreCmControlResponseMessage(PMINI_ADAPTER Adapter,PVOID pvBuffer,UINT *p
|
|||||||
|
|
||||||
(*puBufferLength) = sizeof(stLocalSFAddIndication);
|
(*puBufferLength) = sizeof(stLocalSFAddIndication);
|
||||||
*(stLocalSFAddIndication *)pvBuffer = *pstAddIndication;
|
*(stLocalSFAddIndication *)pvBuffer = *pstAddIndication;
|
||||||
bcm_kfree(pstAddIndication);
|
kfree(pstAddIndication);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1931,7 +1855,7 @@ static inline stLocalSFAddIndicationAlt
|
|||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "============================================================");
|
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "============================================================");
|
||||||
return pstAddIndicationDest;
|
return pstAddIndicationDest;
|
||||||
failed_restore_sf_param:
|
failed_restore_sf_param:
|
||||||
bcm_kfree(pstAddIndicationDest);
|
kfree(pstAddIndicationDest);
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "<=====" );
|
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "<=====" );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -1988,7 +1912,7 @@ ULONG SetUpTargetDsxBuffers(PMINI_ADAPTER Adapter)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG GetNextTargetBufferLocation(PMINI_ADAPTER Adapter,B_UINT16 tid)
|
static ULONG GetNextTargetBufferLocation(PMINI_ADAPTER Adapter,B_UINT16 tid)
|
||||||
{
|
{
|
||||||
ULONG ulTargetDSXBufferAddress;
|
ULONG ulTargetDSXBufferAddress;
|
||||||
ULONG ulTargetDsxBufferIndexToUse,ulMaxTry;
|
ULONG ulTargetDsxBufferIndexToUse,ulMaxTry;
|
||||||
@ -2049,7 +1973,7 @@ INT FreeAdapterDsxBuffer(PMINI_ADAPTER Adapter)
|
|||||||
{
|
{
|
||||||
if(Adapter->caDsxReqResp)
|
if(Adapter->caDsxReqResp)
|
||||||
{
|
{
|
||||||
bcm_kfree(Adapter->caDsxReqResp);
|
kfree(Adapter->caDsxReqResp);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -2102,7 +2026,7 @@ BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter, /**<Pointer to the Adap
|
|||||||
|
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " VCID = %x", ntohs(pstAddIndication->u16VCID));
|
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " VCID = %x", ntohs(pstAddIndication->u16VCID));
|
||||||
CopyBufferToControlPacket(Adapter,(PVOID)Adapter->caDsxReqResp);
|
CopyBufferToControlPacket(Adapter,(PVOID)Adapter->caDsxReqResp);
|
||||||
bcm_kfree(pstAddIndication);
|
kfree(pstAddIndication);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DSA_RSP:
|
case DSA_RSP:
|
||||||
@ -2118,7 +2042,7 @@ BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter, /**<Pointer to the Adap
|
|||||||
case DSA_ACK:
|
case DSA_ACK:
|
||||||
{
|
{
|
||||||
UINT uiSearchRuleIndex=0;
|
UINT uiSearchRuleIndex=0;
|
||||||
struct timeval tv = {0};
|
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "VCID:0x%X",
|
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "VCID:0x%X",
|
||||||
ntohs(pstAddIndication->u16VCID));
|
ntohs(pstAddIndication->u16VCID));
|
||||||
uiSearchRuleIndex=SearchFreeSfid(Adapter);
|
uiSearchRuleIndex=SearchFreeSfid(Adapter);
|
||||||
@ -2169,7 +2093,7 @@ BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter, /**<Pointer to the Adap
|
|||||||
Adapter->PackInfo[uiSearchRuleIndex].bActive=FALSE;
|
Adapter->PackInfo[uiSearchRuleIndex].bActive=FALSE;
|
||||||
Adapter->PackInfo[uiSearchRuleIndex].bValid=FALSE;
|
Adapter->PackInfo[uiSearchRuleIndex].bValid=FALSE;
|
||||||
Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value=0;
|
Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value=0;
|
||||||
bcm_kfree(pstAddIndication);
|
kfree(pstAddIndication);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(psfLocalSet->bValid && (pstAddIndication->u8CC == 0))
|
else if(psfLocalSet->bValid && (pstAddIndication->u8CC == 0))
|
||||||
@ -2200,14 +2124,13 @@ BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter, /**<Pointer to the Adap
|
|||||||
if(!Adapter->LinkUpStatus)
|
if(!Adapter->LinkUpStatus)
|
||||||
{
|
{
|
||||||
netif_carrier_on(Adapter->dev);
|
netif_carrier_on(Adapter->dev);
|
||||||
netif_start_queue(Adapter->dev);
|
netif_start_queue(Adapter->dev);
|
||||||
Adapter->LinkUpStatus = 1;
|
Adapter->LinkUpStatus = 1;
|
||||||
do_gettimeofday(&tv);
|
if (netif_msg_link(Adapter))
|
||||||
|
pr_info(PFX "%s: link up\n", Adapter->dev->name);
|
||||||
atomic_set(&Adapter->TxPktAvail, 1);
|
atomic_set(&Adapter->TxPktAvail, 1);
|
||||||
wake_up(&Adapter->tx_packet_wait_queue);
|
wake_up(&Adapter->tx_packet_wait_queue);
|
||||||
Adapter->liTimeSinceLastNetEntry = tv.tv_sec;
|
Adapter->liTimeSinceLastNetEntry = get_seconds();
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "============Tx Service Flow Created!");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2218,13 +2141,13 @@ BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter, /**<Pointer to the Adap
|
|||||||
Adapter->PackInfo[uiSearchRuleIndex].bActive=FALSE;
|
Adapter->PackInfo[uiSearchRuleIndex].bActive=FALSE;
|
||||||
Adapter->PackInfo[uiSearchRuleIndex].bValid=FALSE;
|
Adapter->PackInfo[uiSearchRuleIndex].bValid=FALSE;
|
||||||
Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value=0;
|
Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value=0;
|
||||||
bcm_kfree(pstAddIndication);
|
kfree(pstAddIndication);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0, "DSA ACK did not get valid SFID");
|
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0, "DSA ACK did not get valid SFID");
|
||||||
bcm_kfree(pstAddIndication);
|
kfree(pstAddIndication);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2239,7 +2162,7 @@ BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter, /**<Pointer to the Adap
|
|||||||
((stLocalSFChangeIndicationAlt*)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSC_RSP;
|
((stLocalSFChangeIndicationAlt*)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSC_RSP;
|
||||||
|
|
||||||
CopyBufferToControlPacket(Adapter,(PVOID)Adapter->caDsxReqResp);
|
CopyBufferToControlPacket(Adapter,(PVOID)Adapter->caDsxReqResp);
|
||||||
bcm_kfree(pstAddIndication);
|
kfree(pstAddIndication);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DSC_RSP:
|
case DSC_RSP:
|
||||||
@ -2312,13 +2235,13 @@ BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter, /**<Pointer to the Adap
|
|||||||
else if(pstChangeIndication->u8CC == 6)
|
else if(pstChangeIndication->u8CC == 6)
|
||||||
{
|
{
|
||||||
deleteSFBySfid(Adapter,uiSearchRuleIndex);
|
deleteSFBySfid(Adapter,uiSearchRuleIndex);
|
||||||
bcm_kfree(pstAddIndication);
|
kfree(pstAddIndication);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0, "DSC ACK did not get valid SFID");
|
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0, "DSC ACK did not get valid SFID");
|
||||||
bcm_kfree(pstAddIndication);
|
kfree(pstAddIndication);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2355,7 +2278,7 @@ BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter, /**<Pointer to the Adap
|
|||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "DSD ACK Rcd, let App handle it\n");
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "DSD ACK Rcd, let App handle it\n");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
bcm_kfree(pstAddIndication);
|
kfree(pstAddIndication);
|
||||||
return FALSE ;
|
return FALSE ;
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -150,8 +150,6 @@ typedef struct stLocalSFChangeIndicationAlt{
|
|||||||
|
|
||||||
ULONG StoreCmControlResponseMessage(PMINI_ADAPTER Adapter,PVOID pvBuffer,UINT *puBufferLength);
|
ULONG StoreCmControlResponseMessage(PMINI_ADAPTER Adapter,PVOID pvBuffer,UINT *puBufferLength);
|
||||||
|
|
||||||
ULONG GetNextTargetBufferLocation(PMINI_ADAPTER Adapter,B_UINT16 tid);
|
|
||||||
|
|
||||||
INT AllocAdapterDsxBuffer(PMINI_ADAPTER Adapter);
|
INT AllocAdapterDsxBuffer(PMINI_ADAPTER Adapter);
|
||||||
|
|
||||||
INT FreeAdapterDsxBuffer(PMINI_ADAPTER Adapter);
|
INT FreeAdapterDsxBuffer(PMINI_ADAPTER Adapter);
|
||||||
@ -159,7 +157,6 @@ ULONG SetUpTargetDsxBuffers(PMINI_ADAPTER Adapter);
|
|||||||
|
|
||||||
BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter,PVOID pvBuffer);
|
BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter,PVOID pvBuffer);
|
||||||
|
|
||||||
VOID deleteSFBySfid(PMINI_ADAPTER Adapter, UINT uiSearchRuleIndex);
|
|
||||||
|
|
||||||
#pragma pack (pop)
|
#pragma pack (pop)
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#include "headers.h"
|
#include "headers.h"
|
||||||
|
|
||||||
#ifndef BCM_SHM_INTERFACE
|
|
||||||
|
|
||||||
|
|
||||||
#define DDR_DUMP_INTERNAL_DEVICE_MEMORY 0xBFC02B00
|
#define DDR_DUMP_INTERNAL_DEVICE_MEMORY 0xBFC02B00
|
||||||
@ -188,17 +187,6 @@ static DDR_SET_NODE asDPLL_266MHZ[] = {
|
|||||||
{0x0f000840,0x0FFF1B00},
|
{0x0f000840,0x0FFF1B00},
|
||||||
{0x0f000870,0x00000002}
|
{0x0f000870,0x00000002}
|
||||||
};
|
};
|
||||||
#if 0
|
|
||||||
static DDR_SET_NODE asDPLL_800MHZ[] = {
|
|
||||||
{0x0f000810,0x00000F95},
|
|
||||||
{0x0f000810,0x00000F95},
|
|
||||||
{0x0f000810,0x00000F95},
|
|
||||||
{0x0f000820,0x03F1365B},
|
|
||||||
{0x0f000840,0x0FFF0000},
|
|
||||||
{0x0f000880,0x000003DD},
|
|
||||||
{0x0f000860,0x00000000}
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define T3B_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 11 //index for 0x0F007000
|
#define T3B_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 11 //index for 0x0F007000
|
||||||
static DDR_SET_NODE asT3B_DDRSetting133MHz[] = {// # DPLL Clock Setting
|
static DDR_SET_NODE asT3B_DDRSetting133MHz[] = {// # DPLL Clock Setting
|
||||||
@ -788,7 +776,7 @@ int ddr_init(MINI_ADAPTER *Adapter)
|
|||||||
{
|
{
|
||||||
PDDR_SETTING psDDRSetting=NULL;
|
PDDR_SETTING psDDRSetting=NULL;
|
||||||
ULONG RegCount=0;
|
ULONG RegCount=0;
|
||||||
ULONG value = 0;
|
UINT value = 0;
|
||||||
UINT uiResetValue = 0;
|
UINT uiResetValue = 0;
|
||||||
UINT uiClockSetting = 0;
|
UINT uiClockSetting = 0;
|
||||||
int retval = STATUS_SUCCESS;
|
int retval = STATUS_SUCCESS;
|
||||||
@ -982,7 +970,7 @@ int ddr_init(MINI_ADAPTER *Adapter)
|
|||||||
{
|
{
|
||||||
value = psDDRSetting->ulRegValue;
|
value = psDDRSetting->ulRegValue;
|
||||||
}
|
}
|
||||||
retval = wrmalt(Adapter, psDDRSetting->ulRegAddress, (PUINT)&value, sizeof(value));
|
retval = wrmalt(Adapter, psDDRSetting->ulRegAddress, &value, sizeof(value));
|
||||||
if(STATUS_SUCCESS != retval) {
|
if(STATUS_SUCCESS != retval) {
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"%s:%d\n", __FUNCTION__, __LINE__);
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"%s:%d\n", __FUNCTION__, __LINE__);
|
||||||
break;
|
break;
|
||||||
@ -1298,5 +1286,4 @@ int download_ddr_settings(PMINI_ADAPTER Adapter)
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
@ -1,41 +0,0 @@
|
|||||||
#include "headers.h"
|
|
||||||
|
|
||||||
static UINT current_debug_level=BCM_SCREAM;
|
|
||||||
|
|
||||||
int bcm_print_buffer( UINT debug_level, const char *function_name,
|
|
||||||
char *file_name, int line_number, unsigned char *buffer, int bufferlen, enum _BASE_TYPE base)
|
|
||||||
{
|
|
||||||
static const char * const buff_dump_base[] = {
|
|
||||||
"DEC", "HEX", "OCT", "BIN"
|
|
||||||
};
|
|
||||||
if(debug_level>=current_debug_level)
|
|
||||||
{
|
|
||||||
int i=0;
|
|
||||||
printk("\n%s:%s:%d:Buffer dump of size 0x%x in the %s:\n", file_name, function_name, line_number, bufferlen, buff_dump_base[1]);
|
|
||||||
for(;i<bufferlen;i++)
|
|
||||||
{
|
|
||||||
if(i && !(i%16) )
|
|
||||||
printk("\n");
|
|
||||||
switch(base)
|
|
||||||
{
|
|
||||||
case BCM_BASE_TYPE_DEC:
|
|
||||||
printk("%03d ", buffer[i]);
|
|
||||||
break;
|
|
||||||
case BCM_BASE_TYPE_OCT:
|
|
||||||
printk("%0x03o ", buffer[i]);
|
|
||||||
break;
|
|
||||||
case BCM_BASE_TYPE_BIN:
|
|
||||||
printk("%02x ", buffer[i]);
|
|
||||||
break;
|
|
||||||
case BCM_BASE_TYPE_HEX:
|
|
||||||
default:
|
|
||||||
printk("%02X ", buffer[i]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printk("\n");
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -9,34 +9,6 @@
|
|||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#define NONE 0xFFFF
|
#define NONE 0xFFFF
|
||||||
|
|
||||||
typedef enum _BASE_TYPE
|
|
||||||
{
|
|
||||||
BCM_BASE_TYPE_DEC,
|
|
||||||
BCM_BASE_TYPE_OCT,
|
|
||||||
BCM_BASE_TYPE_BIN,
|
|
||||||
BCM_BASE_TYPE_HEX,
|
|
||||||
BCM_BASE_TYPE_NONE,
|
|
||||||
} BASE_TYPE, *PBASE_TYPE;
|
|
||||||
|
|
||||||
int bcm_print_buffer( UINT debug_level, const char *function_name,
|
|
||||||
char *file_name, int line_number, unsigned char *buffer, int bufferlen, BASE_TYPE base);
|
|
||||||
|
|
||||||
#ifdef BCM_SHM_INTERFACE
|
|
||||||
#define CPE_VIRTUAL_ERROR_CODE_BASE_ADDR (0xBFC02E00 + 0x4C)
|
|
||||||
// ERROR codes for debugging
|
|
||||||
extern unsigned char u32ErrorCounter ;
|
|
||||||
#define ERROR_DEVICE_REMOVED 0x1
|
|
||||||
#define ERROR_LEADER_LENGTH_ZERO 0x2
|
|
||||||
#define ERROR_LEADER_LENGTH_CORRUPTED 0x3
|
|
||||||
#define ERROR_NO_SKBUFF 0x4
|
|
||||||
|
|
||||||
#define ERROR_DL_MODULE 0xaa000000
|
|
||||||
extern void CPE_ERROR_LOG(unsigned int module,unsigned int code);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -242,43 +214,33 @@ typedef struct _S_BCM_DEBUG_STATE {
|
|||||||
|
|
||||||
//--- Only for direct printk's; "hidden" to API.
|
//--- Only for direct printk's; "hidden" to API.
|
||||||
#define DBG_TYPE_PRINTK 3
|
#define DBG_TYPE_PRINTK 3
|
||||||
#define PRINTKS_ON 1 // "hidden" from API, set to 0 to turn off all printk's
|
|
||||||
|
|
||||||
#define BCM_DEBUG_PRINT(Adapter, Type, SubType, dbg_level, string, args...) do { \
|
#define BCM_DEBUG_PRINT(Adapter, Type, SubType, dbg_level, string, args...) \
|
||||||
if ((DBG_TYPE_PRINTK == Type) && (PRINTKS_ON)) { \
|
do { \
|
||||||
printk ("%s:" string, __FUNCTION__, ##args); \
|
if (DBG_TYPE_PRINTK == Type) \
|
||||||
printk("\n"); \
|
pr_info("%s:" string, __func__, ##args); \
|
||||||
} else if (!Adapter) \
|
else if (Adapter && \
|
||||||
; \
|
(dbg_level & DBG_LVL_BITMASK) <= Adapter->stDebugState.debug_level && \
|
||||||
else { \
|
(Type & Adapter->stDebugState.type) && \
|
||||||
if (((dbg_level & DBG_LVL_BITMASK) <= Adapter->stDebugState.debug_level) && \
|
(SubType & Adapter->stDebugState.subtype[Type])) { \
|
||||||
((Type & Adapter->stDebugState.type) && (SubType & Adapter->stDebugState.subtype[Type]))) { \
|
if (dbg_level & DBG_NO_FUNC_PRINT) \
|
||||||
if (dbg_level & DBG_NO_FUNC_PRINT) \
|
printk(KERN_DEBUG string, ##args); \
|
||||||
printk (string, ##args); \
|
else \
|
||||||
else \
|
printk(KERN_DEBUG "%s:" string, __func__, ##args); \
|
||||||
{ \
|
} \
|
||||||
printk ("%s:" string, __FUNCTION__, ##args); \
|
} while (0)
|
||||||
printk("\n"); \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define BCM_DEBUG_PRINT_BUFFER(Adapter, Type, SubType, dbg_level, buffer, bufferlen) do { \
|
#define BCM_DEBUG_PRINT_BUFFER(Adapter, Type, SubType, dbg_level, buffer, bufferlen) do { \
|
||||||
if ((DBG_TYPE_PRINTK == Type) && (PRINTKS_ON)) { \
|
if (DBG_TYPE_PRINTK == Type || \
|
||||||
bcm_print_buffer( dbg_level, __FUNCTION__, __FILE__, __LINE__, buffer, bufferlen, BCM_BASE_TYPE_HEX); \
|
(Adapter && \
|
||||||
} else if (!Adapter) \
|
(dbg_level & DBG_LVL_BITMASK) <= Adapter->stDebugState.debug_level && \
|
||||||
; \
|
(Type & Adapter->stDebugState.type) && \
|
||||||
else { \
|
(SubType & Adapter->stDebugState.subtype[Type]))) { \
|
||||||
if (((dbg_level & DBG_LVL_BITMASK) <= Adapter->stDebugState.debug_level) && \
|
printk(KERN_DEBUG "%s:\n", __func__); \
|
||||||
((Type & Adapter->stDebugState.type) && (SubType & Adapter->stDebugState.subtype[Type]))) { \
|
print_hex_dump(KERN_DEBUG, " ", DUMP_PREFIX_OFFSET, \
|
||||||
if (dbg_level & DBG_NO_FUNC_PRINT) \
|
16, 1, buffer, bufferlen, false); \
|
||||||
bcm_print_buffer( dbg_level, NULL, NULL, __LINE__, buffer, bufferlen, BCM_BASE_TYPE_HEX); \
|
} \
|
||||||
else \
|
} while(0)
|
||||||
bcm_print_buffer( dbg_level, __FUNCTION__, __FILE__, __LINE__, buffer, bufferlen, BCM_BASE_TYPE_HEX); \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
|
|
||||||
#define BCM_SHOW_DEBUG_BITMAP(Adapter) do { \
|
#define BCM_SHOW_DEBUG_BITMAP(Adapter) do { \
|
||||||
|
@ -11,8 +11,7 @@ When a control packet is received, analyze the
|
|||||||
Enqueue the control packet for Application.
|
Enqueue the control packet for Application.
|
||||||
@return None
|
@return None
|
||||||
*/
|
*/
|
||||||
VOID handle_rx_control_packet(PMINI_ADAPTER Adapter, /**<Pointer to the Adapter structure*/
|
static VOID handle_rx_control_packet(PMINI_ADAPTER Adapter, struct sk_buff *skb)
|
||||||
struct sk_buff *skb) /**<Pointer to the socket buffer*/
|
|
||||||
{
|
{
|
||||||
PPER_TARANG_DATA pTarang = NULL;
|
PPER_TARANG_DATA pTarang = NULL;
|
||||||
BOOLEAN HighPriorityMessage = FALSE;
|
BOOLEAN HighPriorityMessage = FALSE;
|
||||||
@ -20,8 +19,10 @@ VOID handle_rx_control_packet(PMINI_ADAPTER Adapter, /**<Pointer to the Adapter
|
|||||||
CHAR cntrl_msg_mask_bit = 0;
|
CHAR cntrl_msg_mask_bit = 0;
|
||||||
BOOLEAN drop_pkt_flag = TRUE ;
|
BOOLEAN drop_pkt_flag = TRUE ;
|
||||||
USHORT usStatus = *(PUSHORT)(skb->data);
|
USHORT usStatus = *(PUSHORT)(skb->data);
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "=====>");
|
|
||||||
/* Get the Leader field */
|
if (netif_msg_pktdata(Adapter))
|
||||||
|
print_hex_dump(KERN_DEBUG, PFX "rx control: ", DUMP_PREFIX_NONE,
|
||||||
|
16, 1, skb->data, skb->len, 0);
|
||||||
|
|
||||||
switch(usStatus)
|
switch(usStatus)
|
||||||
{
|
{
|
||||||
@ -134,7 +135,7 @@ VOID handle_rx_control_packet(PMINI_ADAPTER Adapter, /**<Pointer to the Adapter
|
|||||||
}
|
}
|
||||||
up(&Adapter->RxAppControlQueuelock);
|
up(&Adapter->RxAppControlQueuelock);
|
||||||
wake_up(&Adapter->process_read_wait_queue);
|
wake_up(&Adapter->process_read_wait_queue);
|
||||||
bcm_kfree_skb(skb);
|
dev_kfree_skb(skb);
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "After wake_up_interruptible");
|
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "After wake_up_interruptible");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,33 +186,7 @@ int control_packet_handler (PMINI_ADAPTER Adapter /**< pointer to adapter obje
|
|||||||
{
|
{
|
||||||
DEQUEUEPACKET(Adapter->RxControlHead,Adapter->RxControlTail);
|
DEQUEUEPACKET(Adapter->RxControlHead,Adapter->RxControlTail);
|
||||||
// Adapter->RxControlHead=ctrl_packet->next;
|
// Adapter->RxControlHead=ctrl_packet->next;
|
||||||
((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats.rx_packets++;
|
|
||||||
((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats.rx_bytes+=
|
|
||||||
((PLEADER)ctrl_packet->data)->PLength;
|
|
||||||
}
|
}
|
||||||
#if 0 //Idle mode debug profiling...
|
|
||||||
if(*(PUSHORT)ctrl_packet->data == IDLE_MODE_STATUS)
|
|
||||||
{
|
|
||||||
puiBuffer = (PUINT)(ctrl_packet->data +sizeof(USHORT));
|
|
||||||
if((ntohl(*puiBuffer) == GO_TO_IDLE_MODE_PAYLOAD))
|
|
||||||
{
|
|
||||||
memset(&tv, 0, sizeof(tv));
|
|
||||||
do_gettimeofday(&tv);
|
|
||||||
if((ntohl(*(puiBuffer+1)) == 0))
|
|
||||||
{
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "IdleMode Wake-up Msg from f/w at time :%ld ms", tv.tv_sec *1000 + tv.tv_usec /1000);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "IdleMode req Msg from f/w at time :%ld ms", tv.tv_sec *1000 + tv.tv_usec /1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if((ntohl(*puiBuffer) == IDLE_MODE_SF_UPDATE_MSG))
|
|
||||||
{
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "GOT IDLE_MODE_SF_UPDATE MSG at time :%ld ms", tv.tv_sec *1000 + tv.tv_usec /1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
spin_unlock_irqrestore (&Adapter->control_queue_lock, flags);
|
spin_unlock_irqrestore (&Adapter->control_queue_lock, flags);
|
||||||
handle_rx_control_packet(Adapter, ctrl_packet);
|
handle_rx_control_packet(Adapter, ctrl_packet);
|
||||||
@ -234,7 +209,7 @@ INT flushAllAppQ(void)
|
|||||||
{
|
{
|
||||||
PacketToDrop=pTarang->RxAppControlHead;
|
PacketToDrop=pTarang->RxAppControlHead;
|
||||||
DEQUEUEPACKET(pTarang->RxAppControlHead,pTarang->RxAppControlTail);
|
DEQUEUEPACKET(pTarang->RxAppControlHead,pTarang->RxAppControlTail);
|
||||||
bcm_kfree_skb(PacketToDrop);
|
dev_kfree_skb(PacketToDrop);
|
||||||
}
|
}
|
||||||
pTarang->AppCtrlQueueLen = 0;
|
pTarang->AppCtrlQueueLen = 0;
|
||||||
//dropped contrl packet statistics also should be reset.
|
//dropped contrl packet statistics also should be reset.
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
#ifndef _HOST_MIBS_H
|
|
||||||
#define _HOST_MIBS_H
|
|
||||||
|
|
||||||
INT ProcessGetHostMibs(PMINI_ADAPTER Adapter,
|
|
||||||
PVOID ioBuffer,
|
|
||||||
ULONG inputBufferLength);
|
|
||||||
#endif
|
|
@ -1,5 +1,9 @@
|
|||||||
#include "headers.h"
|
#include "headers.h"
|
||||||
|
|
||||||
|
static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header);
|
||||||
|
static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header);
|
||||||
|
static VOID DumpIpv6Header(IPV6Header *pstIpv6Header);
|
||||||
|
|
||||||
static UCHAR * GetNextIPV6ChainedHeader(UCHAR **ppucPayload,UCHAR *pucNextHeader,BOOLEAN *bParseDone,USHORT *pusPayloadLength)
|
static UCHAR * GetNextIPV6ChainedHeader(UCHAR **ppucPayload,UCHAR *pucNextHeader,BOOLEAN *bParseDone,USHORT *pusPayloadLength)
|
||||||
{
|
{
|
||||||
UCHAR *pucRetHeaderPtr = NULL;
|
UCHAR *pucRetHeaderPtr = NULL;
|
||||||
@ -257,7 +261,7 @@ USHORT IpVersion6(PMINI_ADAPTER Adapter, /**< Pointer to the driver control stru
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header)
|
static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header)
|
||||||
{
|
{
|
||||||
UINT uiLoopIndex=0;
|
UINT uiLoopIndex=0;
|
||||||
UINT uiIpv6AddIndex=0;
|
UINT uiIpv6AddIndex=0;
|
||||||
@ -310,7 +314,7 @@ BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pst
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header)
|
static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header)
|
||||||
{
|
{
|
||||||
UINT uiLoopIndex=0;
|
UINT uiLoopIndex=0;
|
||||||
UINT uiIpv6AddIndex=0;
|
UINT uiIpv6AddIndex=0;
|
||||||
@ -376,7 +380,7 @@ VOID DumpIpv6Address(ULONG *puIpv6Address)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID DumpIpv6Header(IPV6Header *pstIpv6Header)
|
static VOID DumpIpv6Header(IPV6Header *pstIpv6Header)
|
||||||
{
|
{
|
||||||
UCHAR ucVersion;
|
UCHAR ucVersion;
|
||||||
UCHAR ucPrio ;
|
UCHAR ucPrio ;
|
||||||
|
@ -101,15 +101,12 @@ typedef enum _E_IPADDR_CONTEXT
|
|||||||
|
|
||||||
|
|
||||||
//Function Prototypes
|
//Function Prototypes
|
||||||
BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header);
|
|
||||||
BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header);
|
|
||||||
|
|
||||||
USHORT IpVersion6(PMINI_ADAPTER Adapter, /**< Pointer to the driver control structure */
|
USHORT IpVersion6(PMINI_ADAPTER Adapter, /**< Pointer to the driver control structure */
|
||||||
PVOID pcIpHeader, /**<Pointer to the IP Hdr of the packet*/
|
PVOID pcIpHeader, /**<Pointer to the IP Hdr of the packet*/
|
||||||
S_CLASSIFIER_RULE *pstClassifierRule );
|
S_CLASSIFIER_RULE *pstClassifierRule );
|
||||||
|
|
||||||
VOID DumpIpv6Address(ULONG *puIpv6Address);
|
VOID DumpIpv6Address(ULONG *puIpv6Address);
|
||||||
VOID DumpIpv6Header(IPV6Header *pstIpv6Header);
|
|
||||||
|
|
||||||
extern BOOLEAN MatchSrcPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushSrcPort);
|
extern BOOLEAN MatchSrcPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushSrcPort);
|
||||||
extern BOOLEAN MatchDestPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushSrcPort);
|
extern BOOLEAN MatchDestPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushSrcPort);
|
||||||
|
@ -1,20 +1,18 @@
|
|||||||
#include "headers.h"
|
#include "headers.h"
|
||||||
|
|
||||||
#ifndef BCM_SHM_INTERFACE
|
|
||||||
|
|
||||||
int InterfaceFileDownload( PVOID arg,
|
int InterfaceFileDownload( PVOID arg,
|
||||||
struct file *flp,
|
struct file *flp,
|
||||||
unsigned int on_chip_loc)
|
unsigned int on_chip_loc)
|
||||||
{
|
{
|
||||||
char *buff=NULL;
|
|
||||||
// unsigned int reg=0;
|
// unsigned int reg=0;
|
||||||
mm_segment_t oldfs={0};
|
mm_segment_t oldfs={0};
|
||||||
int errno=0, len=0 /*,is_config_file = 0*/;
|
int errno=0, len=0 /*,is_config_file = 0*/;
|
||||||
loff_t pos=0;
|
loff_t pos=0;
|
||||||
PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg;
|
PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg;
|
||||||
//PMINI_ADAPTER Adapter = psIntfAdapter->psAdapter;
|
//PMINI_ADAPTER Adapter = psIntfAdapter->psAdapter;
|
||||||
|
char *buff=kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL);
|
||||||
|
|
||||||
buff=(PCHAR)kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL);
|
|
||||||
if(!buff)
|
if(!buff)
|
||||||
{
|
{
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@ -49,7 +47,7 @@ int InterfaceFileDownload( PVOID arg,
|
|||||||
on_chip_loc+=MAX_TRANSFER_CTRL_BYTE_USB;
|
on_chip_loc+=MAX_TRANSFER_CTRL_BYTE_USB;
|
||||||
}/* End of for(;;)*/
|
}/* End of for(;;)*/
|
||||||
|
|
||||||
bcm_kfree(buff);
|
kfree(buff);
|
||||||
return errno;
|
return errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +55,7 @@ int InterfaceFileReadbackFromChip( PVOID arg,
|
|||||||
struct file *flp,
|
struct file *flp,
|
||||||
unsigned int on_chip_loc)
|
unsigned int on_chip_loc)
|
||||||
{
|
{
|
||||||
char *buff=NULL, *buff_readback=NULL;
|
char *buff, *buff_readback;
|
||||||
unsigned int reg=0;
|
unsigned int reg=0;
|
||||||
mm_segment_t oldfs={0};
|
mm_segment_t oldfs={0};
|
||||||
int errno=0, len=0, is_config_file = 0;
|
int errno=0, len=0, is_config_file = 0;
|
||||||
@ -66,12 +64,12 @@ int InterfaceFileReadbackFromChip( PVOID arg,
|
|||||||
INT Status = STATUS_SUCCESS;
|
INT Status = STATUS_SUCCESS;
|
||||||
PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg;
|
PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg;
|
||||||
|
|
||||||
buff=(PCHAR)kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_DMA);
|
buff=kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_DMA);
|
||||||
buff_readback=(PCHAR)kmalloc(MAX_TRANSFER_CTRL_BYTE_USB , GFP_DMA);
|
buff_readback=kmalloc(MAX_TRANSFER_CTRL_BYTE_USB , GFP_DMA);
|
||||||
if(!buff || !buff_readback)
|
if(!buff || !buff_readback)
|
||||||
{
|
{
|
||||||
bcm_kfree(buff);
|
kfree(buff);
|
||||||
bcm_kfree(buff_readback);
|
kfree(buff_readback);
|
||||||
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
@ -138,8 +136,8 @@ int InterfaceFileReadbackFromChip( PVOID arg,
|
|||||||
on_chip_loc+=MAX_TRANSFER_CTRL_BYTE_USB;
|
on_chip_loc+=MAX_TRANSFER_CTRL_BYTE_USB;
|
||||||
}/* End of while(1)*/
|
}/* End of while(1)*/
|
||||||
exit:
|
exit:
|
||||||
bcm_kfree(buff);
|
kfree(buff);
|
||||||
bcm_kfree(buff_readback);
|
kfree(buff_readback);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,7 +163,7 @@ static int bcm_download_config_file(PMINI_ADAPTER Adapter,
|
|||||||
psFwInfo->pvMappedFirmwareAddress, psFwInfo->u32FirmwareLength);
|
psFwInfo->pvMappedFirmwareAddress, psFwInfo->u32FirmwareLength);
|
||||||
if(retval)
|
if(retval)
|
||||||
{
|
{
|
||||||
bcm_kfree (Adapter->pstargetparams);
|
kfree(Adapter->pstargetparams);
|
||||||
Adapter->pstargetparams = NULL;
|
Adapter->pstargetparams = NULL;
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
@ -231,41 +229,6 @@ static int bcm_download_config_file(PMINI_ADAPTER Adapter,
|
|||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
static int bcm_download_buffer(PMINI_ADAPTER Adapter,
|
|
||||||
unsigned char *mappedbuffer, unsigned int u32FirmwareLength,
|
|
||||||
unsigned long u32StartingAddress)
|
|
||||||
{
|
|
||||||
char *buff=NULL;
|
|
||||||
unsigned int len = 0;
|
|
||||||
int retval = STATUS_SUCCESS;
|
|
||||||
buff = kzalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL);
|
|
||||||
|
|
||||||
len = u32FirmwareLength;
|
|
||||||
|
|
||||||
while(u32FirmwareLength)
|
|
||||||
{
|
|
||||||
len = MIN_VAL (u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB);
|
|
||||||
if(STATUS_SUCCESS != (retval = copy_from_user(buff,
|
|
||||||
(unsigned char *)mappedbuffer, len)))
|
|
||||||
{
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "copy_from_user failed\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
retval = wrm (Adapter, u32StartingAddress, buff, len);
|
|
||||||
if(retval)
|
|
||||||
{
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "wrm failed\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
u32StartingAddress += len;
|
|
||||||
u32FirmwareLength -= len;
|
|
||||||
mappedbuffer +=len;
|
|
||||||
}
|
|
||||||
bcm_kfree(buff);
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
static int bcm_compare_buff_contents(unsigned char *readbackbuff,
|
static int bcm_compare_buff_contents(unsigned char *readbackbuff,
|
||||||
unsigned char *buff,unsigned int len)
|
unsigned char *buff,unsigned int len)
|
||||||
{
|
{
|
||||||
@ -297,58 +260,6 @@ static int bcm_compare_buff_contents(unsigned char *readbackbuff,
|
|||||||
}
|
}
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
static int bcm_buffer_readback(PMINI_ADAPTER Adapter,
|
|
||||||
unsigned char *mappedbuffer, unsigned int u32FirmwareLength,
|
|
||||||
unsigned long u32StartingAddress)
|
|
||||||
{
|
|
||||||
unsigned char *buff = NULL;
|
|
||||||
unsigned char *readbackbuff = NULL;
|
|
||||||
unsigned int len = u32FirmwareLength;
|
|
||||||
int retval = STATUS_SUCCESS;
|
|
||||||
|
|
||||||
buff=(unsigned char *)kzalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL);
|
|
||||||
if(NULL == buff)
|
|
||||||
return -ENOMEM;
|
|
||||||
readbackbuff = (unsigned char *)kzalloc(MAX_TRANSFER_CTRL_BYTE_USB,
|
|
||||||
GFP_KERNEL);
|
|
||||||
if(NULL == readbackbuff)
|
|
||||||
{
|
|
||||||
bcm_kfree(buff);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
while (u32FirmwareLength && !retval)
|
|
||||||
{
|
|
||||||
len = MIN_VAL (u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB);
|
|
||||||
|
|
||||||
/* read from the appl buff and then read from the target, compare */
|
|
||||||
if(STATUS_SUCCESS != (retval = copy_from_user(buff,
|
|
||||||
(unsigned char *)mappedbuffer, len)))
|
|
||||||
{
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "copy_from_user failed\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
retval = rdm (Adapter, u32StartingAddress, readbackbuff, len);
|
|
||||||
if(retval)
|
|
||||||
{
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "rdm failed\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (STATUS_SUCCESS !=
|
|
||||||
(retval = bcm_compare_buff_contents (readbackbuff, buff, len)))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
u32StartingAddress += len;
|
|
||||||
u32FirmwareLength -= len;
|
|
||||||
mappedbuffer +=len;
|
|
||||||
}/* end of while (u32FirmwareLength && !retval) */
|
|
||||||
bcm_kfree(buff);
|
|
||||||
bcm_kfree(readbackbuff);
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
int bcm_ioctl_fw_download(PMINI_ADAPTER Adapter, FIRMWARE_INFO *psFwInfo)
|
int bcm_ioctl_fw_download(PMINI_ADAPTER Adapter, FIRMWARE_INFO *psFwInfo)
|
||||||
{
|
{
|
||||||
int retval = STATUS_SUCCESS;
|
int retval = STATUS_SUCCESS;
|
||||||
@ -375,7 +286,7 @@ int bcm_ioctl_fw_download(PMINI_ADAPTER Adapter, FIRMWARE_INFO *psFwInfo)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
buff = (PUCHAR)kzalloc(psFwInfo->u32FirmwareLength,GFP_KERNEL);
|
buff = kzalloc(psFwInfo->u32FirmwareLength,GFP_KERNEL);
|
||||||
if(buff==NULL)
|
if(buff==NULL)
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Failed in allocation memory");
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Failed in allocation memory");
|
||||||
@ -389,23 +300,6 @@ int bcm_ioctl_fw_download(PMINI_ADAPTER Adapter, FIRMWARE_INFO *psFwInfo)
|
|||||||
goto error ;
|
goto error ;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
retval = bcm_download_buffer(Adapter,
|
|
||||||
(unsigned char *)psFwInfo->pvMappedFirmwareAddress,
|
|
||||||
psFwInfo->u32FirmwareLength, psFwInfo->u32StartingAddress);
|
|
||||||
if(retval != STATUS_SUCCESS)
|
|
||||||
{
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "User space buffer download fails....");
|
|
||||||
}
|
|
||||||
retval = bcm_buffer_readback (Adapter,
|
|
||||||
(unsigned char *)psFwInfo->pvMappedFirmwareAddress,
|
|
||||||
psFwInfo->u32FirmwareLength, psFwInfo->u32StartingAddress);
|
|
||||||
|
|
||||||
if(retval != STATUS_SUCCESS)
|
|
||||||
{
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "read back verifier failed ....");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
retval = buffDnldVerify(Adapter,
|
retval = buffDnldVerify(Adapter,
|
||||||
buff,
|
buff,
|
||||||
psFwInfo->u32FirmwareLength,
|
psFwInfo->u32FirmwareLength,
|
||||||
@ -417,7 +311,7 @@ int bcm_ioctl_fw_download(PMINI_ADAPTER Adapter, FIRMWARE_INFO *psFwInfo)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
error:
|
error:
|
||||||
bcm_kfree(buff);
|
kfree(buff);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -450,11 +344,10 @@ static INT buffRdbkVerify(PMINI_ADAPTER Adapter,
|
|||||||
PUCHAR mappedbuffer, UINT u32FirmwareLength,
|
PUCHAR mappedbuffer, UINT u32FirmwareLength,
|
||||||
ULONG u32StartingAddress)
|
ULONG u32StartingAddress)
|
||||||
{
|
{
|
||||||
PUCHAR readbackbuff = NULL;
|
|
||||||
UINT len = u32FirmwareLength;
|
UINT len = u32FirmwareLength;
|
||||||
INT retval = STATUS_SUCCESS;
|
INT retval = STATUS_SUCCESS;
|
||||||
|
PUCHAR readbackbuff = kzalloc(MAX_TRANSFER_CTRL_BYTE_USB,GFP_KERNEL);
|
||||||
|
|
||||||
readbackbuff = (PUCHAR)kzalloc(MAX_TRANSFER_CTRL_BYTE_USB,GFP_KERNEL);
|
|
||||||
if(NULL == readbackbuff)
|
if(NULL == readbackbuff)
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "MEMORY ALLOCATION FAILED");
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "MEMORY ALLOCATION FAILED");
|
||||||
@ -480,7 +373,7 @@ static INT buffRdbkVerify(PMINI_ADAPTER Adapter,
|
|||||||
u32FirmwareLength -= len;
|
u32FirmwareLength -= len;
|
||||||
mappedbuffer +=len;
|
mappedbuffer +=len;
|
||||||
}/* end of while (u32FirmwareLength && !retval) */
|
}/* end of while (u32FirmwareLength && !retval) */
|
||||||
bcm_kfree(readbackbuff);
|
kfree(readbackbuff);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -506,5 +399,4 @@ INT buffDnldVerify(PMINI_ADAPTER Adapter, unsigned char *mappedbuffer, unsigned
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
@ -98,14 +98,6 @@ int InterfaceIdleModeRespond(PMINI_ADAPTER Adapter, unsigned int* puiBuffer)
|
|||||||
Adapter->bTriedToWakeUpFromlowPowerMode = FALSE;
|
Adapter->bTriedToWakeUpFromlowPowerMode = FALSE;
|
||||||
|
|
||||||
wake_up(&Adapter->lowpower_mode_wait_queue);
|
wake_up(&Adapter->lowpower_mode_wait_queue);
|
||||||
#if 0
|
|
||||||
if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY)
|
|
||||||
{
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"LED Thread is Running. Hence Setting the LED Event as IDLEMODE_EXIT");
|
|
||||||
Adapter->DriverState = IDLEMODE_EXIT;
|
|
||||||
wake_up(&Adapter->LEDInfo.notify_led_event);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -154,17 +146,7 @@ int InterfaceIdleModeRespond(PMINI_ADAPTER Adapter, unsigned int* puiBuffer)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int InterfaceAbortIdlemode(PMINI_ADAPTER Adapter, unsigned int Pattern)
|
||||||
VOID InterfaceWriteIdleModeWakePattern(PMINI_ADAPTER Adapter)
|
|
||||||
{
|
|
||||||
/* BeceemWriteMemoryUshort(Adapter, Host2CPU_Mailbox_Low, 0x1d1e);
|
|
||||||
BeceemWriteMemoryUshort(Adapter, Host2CPU_Mailbox_Low, 0x1d1e);
|
|
||||||
BeceemWriteMemoryUshort(Adapter, Host2CPU_Mailbox_Upp, 0xd0ea);
|
|
||||||
BeceemWriteMemoryUshort(Adapter, Host2CPU_Mailbox_Upp, 0xd0ea);*/
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int InterfaceAbortIdlemode(PMINI_ADAPTER Adapter, unsigned int Pattern)
|
|
||||||
{
|
{
|
||||||
int status = STATUS_SUCCESS;
|
int status = STATUS_SUCCESS;
|
||||||
unsigned int value;
|
unsigned int value;
|
||||||
|
@ -7,8 +7,6 @@ INT InterfaceIdleModeRespond(PMINI_ADAPTER Adapter, unsigned int *puiBuffer);
|
|||||||
|
|
||||||
VOID InterfaceWriteIdleModeWakePattern(PMINI_ADAPTER Adapter);
|
VOID InterfaceWriteIdleModeWakePattern(PMINI_ADAPTER Adapter);
|
||||||
|
|
||||||
INT InterfaceAbortIdlemode(PMINI_ADAPTER Adapter, unsigned int Pattern);
|
|
||||||
|
|
||||||
INT InterfaceWakeUp(PMINI_ADAPTER Adapter);
|
INT InterfaceWakeUp(PMINI_ADAPTER Adapter);
|
||||||
|
|
||||||
VOID InterfaceHandleShutdownModeWakeup(PMINI_ADAPTER Adapter);
|
VOID InterfaceHandleShutdownModeWakeup(PMINI_ADAPTER Adapter);
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -8,9 +8,11 @@
|
|||||||
#define BCM_USB_PRODUCT_ID_T3 0x0300
|
#define BCM_USB_PRODUCT_ID_T3 0x0300
|
||||||
#define BCM_USB_PRODUCT_ID_T3B 0x0210
|
#define BCM_USB_PRODUCT_ID_T3B 0x0210
|
||||||
#define BCM_USB_PRODUCT_ID_T3L 0x0220
|
#define BCM_USB_PRODUCT_ID_T3L 0x0220
|
||||||
|
#define BCM_USB_PRODUCT_ID_SM250 0xbccd
|
||||||
#define BCM_USB_PRODUCT_ID_SYM 0x15E
|
#define BCM_USB_PRODUCT_ID_SYM 0x15E
|
||||||
#define BCM_USB_PRODUCT_ID_1901 0xe017
|
#define BCM_USB_PRODUCT_ID_1901 0xe017
|
||||||
#define BCM_USB_PRODUCT_ID_226 0x0132
|
#define BCM_USB_PRODUCT_ID_226 0x0132
|
||||||
|
#define BCM_USB_PRODUCT_ID_ZTE_TU25 0x0007
|
||||||
|
|
||||||
#define BCM_USB_MINOR_BASE 192
|
#define BCM_USB_MINOR_BASE 192
|
||||||
|
|
||||||
@ -19,33 +21,7 @@ INT InterfaceInitialize(void);
|
|||||||
|
|
||||||
INT InterfaceExit(void);
|
INT InterfaceExit(void);
|
||||||
|
|
||||||
#ifndef BCM_SHM_INTERFACE
|
|
||||||
INT InterfaceAdapterInit(PS_INTERFACE_ADAPTER Adapter);
|
|
||||||
|
|
||||||
INT usbbcm_worker_thread(PS_INTERFACE_ADAPTER psIntfAdapter);
|
INT usbbcm_worker_thread(PS_INTERFACE_ADAPTER psIntfAdapter);
|
||||||
|
|
||||||
VOID InterfaceAdapterFree(PS_INTERFACE_ADAPTER psIntfAdapter);
|
|
||||||
|
|
||||||
#else
|
|
||||||
INT InterfaceAdapterInit(PMINI_ADAPTER Adapter);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
ULONG InterfaceClaimAdapter(PMINI_ADAPTER Adapter);
|
|
||||||
|
|
||||||
VOID InterfaceDDRControllerInit(PMINI_ADAPTER Adapter);
|
|
||||||
|
|
||||||
ULONG InterfaceReset(PMINI_ADAPTER Adapter);
|
|
||||||
|
|
||||||
ULONG InterfaceRegisterResources(PMINI_ADAPTER Adapter);
|
|
||||||
|
|
||||||
VOID InterfaceUnRegisterResources(PMINI_ADAPTER Adapter);
|
|
||||||
|
|
||||||
ULONG InterfaceFirmwareDownload(PMINI_ADAPTER Adapter);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#include "headers.h"
|
#include "headers.h"
|
||||||
|
|
||||||
#ifndef BCM_SHM_INTERFACE
|
|
||||||
|
|
||||||
static void read_int_callback(struct urb *urb/*, struct pt_regs *regs*/)
|
static void read_int_callback(struct urb *urb/*, struct pt_regs *regs*/)
|
||||||
{
|
{
|
||||||
@ -8,6 +7,10 @@ static void read_int_callback(struct urb *urb/*, struct pt_regs *regs*/)
|
|||||||
PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)urb->context;
|
PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)urb->context;
|
||||||
PMINI_ADAPTER Adapter = psIntfAdapter->psAdapter ;
|
PMINI_ADAPTER Adapter = psIntfAdapter->psAdapter ;
|
||||||
|
|
||||||
|
if (netif_msg_intr(Adapter))
|
||||||
|
pr_info(PFX "%s: interrupt status %d\n",
|
||||||
|
Adapter->dev->name, status);
|
||||||
|
|
||||||
if(Adapter->device_removed == TRUE)
|
if(Adapter->device_removed == TRUE)
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Device has Got Removed.");
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Device has Got Removed.");
|
||||||
@ -87,7 +90,7 @@ static void read_int_callback(struct urb *urb/*, struct pt_regs *regs*/)
|
|||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Interrupt IN endPoint has got halted/stalled...need to clear this");
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Interrupt IN endPoint has got halted/stalled...need to clear this");
|
||||||
Adapter->bEndPointHalted = TRUE ;
|
Adapter->bEndPointHalted = TRUE ;
|
||||||
wake_up(&Adapter->tx_packet_wait_queue);
|
wake_up(&Adapter->tx_packet_wait_queue);
|
||||||
urb->status = STATUS_SUCCESS ;;
|
urb->status = STATUS_SUCCESS ;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* software-driven interface shutdown */
|
/* software-driven interface shutdown */
|
||||||
@ -164,40 +167,3 @@ INT StartInterruptUrb(PS_INTERFACE_ADAPTER psIntfAdapter)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Function: InterfaceEnableInterrupt
|
|
||||||
|
|
||||||
Description: This is the hardware specific Function for configuring
|
|
||||||
and enabling the interrupts on the device.
|
|
||||||
|
|
||||||
Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context
|
|
||||||
|
|
||||||
|
|
||||||
Return: BCM_STATUS_SUCCESS - If configuring the interrupts was successful.
|
|
||||||
Other - If an error occured.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void InterfaceEnableInterrupt(PMINI_ADAPTER Adapter)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Function: InterfaceDisableInterrupt
|
|
||||||
|
|
||||||
Description: This is the hardware specific Function for disabling the interrupts on the device.
|
|
||||||
|
|
||||||
Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context
|
|
||||||
|
|
||||||
|
|
||||||
Return: BCM_STATUS_SUCCESS - If disabling the interrupts was successful.
|
|
||||||
Other - If an error occured.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void InterfaceDisableInterrupt(PMINI_ADAPTER Adapter)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
@ -1,17 +1,5 @@
|
|||||||
#include "headers.h"
|
#include "headers.h"
|
||||||
|
|
||||||
#ifndef BCM_SHM_INTERFACE
|
|
||||||
|
|
||||||
PS_INTERFACE_ADAPTER
|
|
||||||
InterfaceAdapterGet(PMINI_ADAPTER psAdapter)
|
|
||||||
{
|
|
||||||
if(psAdapter == NULL)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return (PS_INTERFACE_ADAPTER)(psAdapter->pvInterfaceAdapter);
|
|
||||||
}
|
|
||||||
|
|
||||||
INT
|
INT
|
||||||
InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter,
|
InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter,
|
||||||
UINT addr,
|
UINT addr,
|
||||||
@ -102,7 +90,7 @@ InterfaceWRM(PS_INTERFACE_ADAPTER psIntfAdapter,
|
|||||||
if((psIntfAdapter->psAdapter->StopAllXaction == TRUE) && (psIntfAdapter->psAdapter->chip_id >= T3LPB))
|
if((psIntfAdapter->psAdapter->StopAllXaction == TRUE) && (psIntfAdapter->psAdapter->chip_id >= T3LPB))
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL,"Currently Xaction is not allowed on the bus...");
|
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL,"Currently Xaction is not allowed on the bus...");
|
||||||
return EACCES;
|
return -EACCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(psIntfAdapter->bSuspended ==TRUE || psIntfAdapter->bPreparingForBusSuspend == TRUE)
|
if(psIntfAdapter->bSuspended ==TRUE || psIntfAdapter->bPreparingForBusSuspend == TRUE)
|
||||||
@ -236,9 +224,7 @@ VOID Bcm_kill_all_URBs(PS_INTERFACE_ADAPTER psIntfAdapter)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Cancel All submitted TX URB's */
|
/* Cancel All submitted TX URB's */
|
||||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Cancelling All Submitted TX Urbs \n");
|
for(i = 0; i < MAXIMUM_USB_TCB; i++)
|
||||||
|
|
||||||
for(i = 0; i < MAXIMUM_USB_TCB; i++)
|
|
||||||
{
|
{
|
||||||
tempUrb = psIntfAdapter->asUsbTcb[i].urb;
|
tempUrb = psIntfAdapter->asUsbTcb[i].urb;
|
||||||
if(tempUrb)
|
if(tempUrb)
|
||||||
@ -248,9 +234,6 @@ VOID Bcm_kill_all_URBs(PS_INTERFACE_ADAPTER psIntfAdapter)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Cancelling All submitted Rx Urbs \n");
|
|
||||||
|
|
||||||
for(i = 0; i < MAXIMUM_USB_RCB; i++)
|
for(i = 0; i < MAXIMUM_USB_RCB; i++)
|
||||||
{
|
{
|
||||||
tempUrb = psIntfAdapter->asUsbRcb[i].urb;
|
tempUrb = psIntfAdapter->asUsbRcb[i].urb;
|
||||||
@ -261,16 +244,11 @@ VOID Bcm_kill_all_URBs(PS_INTERFACE_ADAPTER psIntfAdapter)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
atomic_set(&psIntfAdapter->uNumTcbUsed, 0);
|
atomic_set(&psIntfAdapter->uNumTcbUsed, 0);
|
||||||
atomic_set(&psIntfAdapter->uCurrTcb, 0);
|
atomic_set(&psIntfAdapter->uCurrTcb, 0);
|
||||||
|
|
||||||
atomic_set(&psIntfAdapter->uNumRcbUsed, 0);
|
atomic_set(&psIntfAdapter->uNumRcbUsed, 0);
|
||||||
atomic_set(&psIntfAdapter->uCurrRcb, 0);
|
atomic_set(&psIntfAdapter->uCurrRcb, 0);
|
||||||
|
|
||||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "TCB: used- %d cur-%d\n", atomic_read(&psIntfAdapter->uNumTcbUsed), atomic_read(&psIntfAdapter->uCurrTcb));
|
|
||||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "RCB: used- %d cur-%d\n", atomic_read(&psIntfAdapter->uNumRcbUsed), atomic_read(&psIntfAdapter->uCurrRcb));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID putUsbSuspend(struct work_struct *work)
|
VOID putUsbSuspend(struct work_struct *work)
|
||||||
@ -282,9 +260,6 @@ VOID putUsbSuspend(struct work_struct *work)
|
|||||||
|
|
||||||
if(psIntfAdapter->bSuspended == FALSE)
|
if(psIntfAdapter->bSuspended == FALSE)
|
||||||
usb_autopm_put_interface(intf);
|
usb_autopm_put_interface(intf);
|
||||||
else
|
|
||||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Interface Resumed Completely\n");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
#ifndef __INTERFACE_MISC_H
|
#ifndef __INTERFACE_MISC_H
|
||||||
#define __INTERFACE_MISC_H
|
#define __INTERFACE_MISC_H
|
||||||
|
|
||||||
PS_INTERFACE_ADAPTER
|
|
||||||
InterfaceAdapterGet(PMINI_ADAPTER psAdapter);
|
|
||||||
|
|
||||||
INT
|
INT
|
||||||
InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter,
|
InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter,
|
||||||
UINT addr,
|
UINT addr,
|
||||||
|
@ -1,5 +1,15 @@
|
|||||||
#include "headers.h"
|
#include "headers.h"
|
||||||
extern int SearchVcid(PMINI_ADAPTER , unsigned short);
|
|
||||||
|
static int SearchVcid(PMINI_ADAPTER Adapter,unsigned short usVcid)
|
||||||
|
{
|
||||||
|
int iIndex=0;
|
||||||
|
|
||||||
|
for(iIndex=(NO_OF_QUEUES-1);iIndex>=0;iIndex--)
|
||||||
|
if(Adapter->PackInfo[iIndex].usVCID_Value == usVcid)
|
||||||
|
return iIndex;
|
||||||
|
return NO_OF_QUEUES+1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static PUSB_RCB
|
static PUSB_RCB
|
||||||
@ -38,13 +48,9 @@ static void read_bulk_callback(struct urb *urb)
|
|||||||
PMINI_ADAPTER Adapter = psIntfAdapter->psAdapter;
|
PMINI_ADAPTER Adapter = psIntfAdapter->psAdapter;
|
||||||
PLEADER pLeader = urb->transfer_buffer;
|
PLEADER pLeader = urb->transfer_buffer;
|
||||||
|
|
||||||
|
if (unlikely(netif_msg_rx_status(Adapter)))
|
||||||
#if 0
|
pr_info(PFX "%s: rx urb status %d length %d\n",
|
||||||
int *puiBuffer = NULL;
|
Adapter->dev->name, urb->status, urb->actual_length);
|
||||||
struct timeval tv;
|
|
||||||
memset(&tv, 0, sizeof(tv));
|
|
||||||
do_gettimeofday(&tv);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if((Adapter->device_removed == TRUE) ||
|
if((Adapter->device_removed == TRUE) ||
|
||||||
(TRUE == Adapter->bEndPointHalted) ||
|
(TRUE == Adapter->bEndPointHalted) ||
|
||||||
@ -89,10 +95,10 @@ static void read_bulk_callback(struct urb *urb)
|
|||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Leader Status:0x%hX, Length:0x%hX, VCID:0x%hX", pLeader->Status,pLeader->PLength,pLeader->Vcid);
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Leader Status:0x%hX, Length:0x%hX, VCID:0x%hX", pLeader->Status,pLeader->PLength,pLeader->Vcid);
|
||||||
if(MAX_CNTL_PKT_SIZE < pLeader->PLength)
|
if(MAX_CNTL_PKT_SIZE < pLeader->PLength)
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Corrupted leader length...%d\n",
|
if (netif_msg_rx_err(Adapter))
|
||||||
pLeader->PLength);
|
pr_info(PFX "%s: corrupted leader length...%d\n",
|
||||||
atomic_inc(&Adapter->RxPacketDroppedCount);
|
Adapter->dev->name, pLeader->PLength);
|
||||||
atomic_add(pLeader->PLength, &Adapter->BadRxByteCount);
|
++Adapter->dev->stats.rx_dropped;
|
||||||
atomic_dec(&psIntfAdapter->uNumRcbUsed);
|
atomic_dec(&psIntfAdapter->uNumRcbUsed);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -145,10 +151,9 @@ static void read_bulk_callback(struct urb *urb)
|
|||||||
skb_put (skb, pLeader->PLength + ETH_HLEN);
|
skb_put (skb, pLeader->PLength + ETH_HLEN);
|
||||||
Adapter->PackInfo[QueueIndex].uiTotalRxBytes+=pLeader->PLength;
|
Adapter->PackInfo[QueueIndex].uiTotalRxBytes+=pLeader->PLength;
|
||||||
Adapter->PackInfo[QueueIndex].uiThisPeriodRxBytes+= pLeader->PLength;
|
Adapter->PackInfo[QueueIndex].uiThisPeriodRxBytes+= pLeader->PLength;
|
||||||
atomic_add(pLeader->PLength, &Adapter->GoodRxByteCount);
|
|
||||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "Recived Data pkt of len :0x%X", pLeader->PLength);
|
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "Recived Data pkt of len :0x%X", pLeader->PLength);
|
||||||
|
|
||||||
if(Adapter->if_up)
|
if(netif_running(Adapter->dev))
|
||||||
{
|
{
|
||||||
/* Moving ahead by ETH_HLEN to the data ptr as received from FW */
|
/* Moving ahead by ETH_HLEN to the data ptr as received from FW */
|
||||||
skb_pull(skb, ETH_HLEN);
|
skb_pull(skb, ETH_HLEN);
|
||||||
@ -173,9 +178,12 @@ static void read_bulk_callback(struct urb *urb)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "i/f not up hance freeing SKB...");
|
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "i/f not up hance freeing SKB...");
|
||||||
bcm_kfree_skb(skb);
|
dev_kfree_skb(skb);
|
||||||
}
|
}
|
||||||
atomic_inc(&Adapter->GoodRxPktCount);
|
|
||||||
|
++Adapter->dev->stats.rx_packets;
|
||||||
|
Adapter->dev->stats.rx_bytes += pLeader->PLength;
|
||||||
|
|
||||||
for(uiIndex = 0 ; uiIndex < MIBS_MAX_HIST_ENTRIES ; uiIndex++)
|
for(uiIndex = 0 ; uiIndex < MIBS_MAX_HIST_ENTRIES ; uiIndex++)
|
||||||
{
|
{
|
||||||
if((pLeader->PLength <= MIBS_PKTSIZEHIST_RANGE*(uiIndex+1))
|
if((pLeader->PLength <= MIBS_PKTSIZEHIST_RANGE*(uiIndex+1))
|
||||||
|
@ -1,50 +1,5 @@
|
|||||||
#include "headers.h"
|
#include "headers.h"
|
||||||
|
|
||||||
#ifndef BCM_SHM_INTERFACE
|
|
||||||
|
|
||||||
/*
|
|
||||||
Function: InterfaceTxDataPacket
|
|
||||||
|
|
||||||
Description: This is the hardware specific Function for Transmitting
|
|
||||||
data packet to the device.
|
|
||||||
|
|
||||||
Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context
|
|
||||||
PVOID Packet - Packet Containing the data to be transmitted
|
|
||||||
USHORT usVcid - VCID on which data packet is to be sent
|
|
||||||
|
|
||||||
|
|
||||||
Return: BCM_STATUS_SUCCESS - If Tx was successful.
|
|
||||||
Other - If an error occured.
|
|
||||||
*/
|
|
||||||
|
|
||||||
ULONG InterfaceTxDataPacket(PMINI_ADAPTER Adapter,PVOID Packet,USHORT usVcid)
|
|
||||||
{
|
|
||||||
ULONG Status = 0;
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Function: InterfaceTxControlPacket
|
|
||||||
|
|
||||||
Description: This is the hardware specific Function for Transmitting
|
|
||||||
control packet to the device.
|
|
||||||
|
|
||||||
Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context
|
|
||||||
PVOID pvBuffer - Buffer containg control packet
|
|
||||||
UINT uiBufferLength - Buffer Length
|
|
||||||
|
|
||||||
Return: BCM_STATUS_SUCCESS - If control packet transmit was successful.
|
|
||||||
Other - If an error occured.
|
|
||||||
*/
|
|
||||||
|
|
||||||
ULONG InterfaceTxControlPacket(PMINI_ADAPTER Adapter,PVOID pvBuffer,UINT uiBufferLength)
|
|
||||||
{
|
|
||||||
ULONG Status = 0;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
/*this is transmit call-back(BULK OUT)*/
|
/*this is transmit call-back(BULK OUT)*/
|
||||||
static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/)
|
static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/)
|
||||||
{
|
{
|
||||||
@ -54,10 +9,10 @@ static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/)
|
|||||||
PMINI_ADAPTER psAdapter = psIntfAdapter->psAdapter ;
|
PMINI_ADAPTER psAdapter = psIntfAdapter->psAdapter ;
|
||||||
BOOLEAN bpowerDownMsg = FALSE ;
|
BOOLEAN bpowerDownMsg = FALSE ;
|
||||||
PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
|
PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
|
||||||
#if 0
|
|
||||||
struct timeval tv;
|
if (unlikely(netif_msg_tx_done(Adapter)))
|
||||||
UINT time_ms = 0;
|
pr_info(PFX "%s: transmit status %d\n", Adapter->dev->name, urb->status);
|
||||||
#endif
|
|
||||||
if(urb->status != STATUS_SUCCESS)
|
if(urb->status != STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
if(urb->status == -EPIPE)
|
if(urb->status == -EPIPE)
|
||||||
@ -78,11 +33,6 @@ static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/)
|
|||||||
|
|
||||||
if(TRUE == psAdapter->bPreparingForLowPowerMode)
|
if(TRUE == psAdapter->bPreparingForLowPowerMode)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
do_gettimeofday(&tv);
|
|
||||||
time_ms = tv.tv_sec *1000 + tv.tv_usec/1000;
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, " %s Idle Mode ACK_Sent got from device at time :0x%x", __FUNCTION__, time_ms);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(((pControlMsg->szData[0] == GO_TO_IDLE_MODE_PAYLOAD) &&
|
if(((pControlMsg->szData[0] == GO_TO_IDLE_MODE_PAYLOAD) &&
|
||||||
(pControlMsg->szData[1] == TARGET_CAN_GO_TO_IDLE_MODE)))
|
(pControlMsg->szData[1] == TARGET_CAN_GO_TO_IDLE_MODE)))
|
||||||
@ -152,17 +102,12 @@ static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/)
|
|||||||
}
|
}
|
||||||
|
|
||||||
err_exit :
|
err_exit :
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35)
|
|
||||||
usb_buffer_free(urb->dev, urb->transfer_buffer_length,
|
|
||||||
urb->transfer_buffer, urb->transfer_dma);
|
|
||||||
#else
|
|
||||||
usb_free_coherent(urb->dev, urb->transfer_buffer_length,
|
usb_free_coherent(urb->dev, urb->transfer_buffer_length,
|
||||||
urb->transfer_buffer, urb->transfer_dma);
|
urb->transfer_buffer, urb->transfer_dma);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static __inline PUSB_TCB GetBulkOutTcb(PS_INTERFACE_ADAPTER psIntfAdapter)
|
static PUSB_TCB GetBulkOutTcb(PS_INTERFACE_ADAPTER psIntfAdapter)
|
||||||
{
|
{
|
||||||
PUSB_TCB pTcb = NULL;
|
PUSB_TCB pTcb = NULL;
|
||||||
UINT index = 0;
|
UINT index = 0;
|
||||||
@ -183,20 +128,14 @@ static __inline PUSB_TCB GetBulkOutTcb(PS_INTERFACE_ADAPTER psIntfAdapter)
|
|||||||
return pTcb;
|
return pTcb;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline int TransmitTcb(PS_INTERFACE_ADAPTER psIntfAdapter, PUSB_TCB pTcb, PVOID data, int len)
|
static int TransmitTcb(PS_INTERFACE_ADAPTER psIntfAdapter, PUSB_TCB pTcb, PVOID data, int len)
|
||||||
{
|
{
|
||||||
|
|
||||||
struct urb *urb = pTcb->urb;
|
struct urb *urb = pTcb->urb;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35)
|
|
||||||
urb->transfer_buffer = usb_buffer_alloc(psIntfAdapter->udev, len,
|
|
||||||
GFP_ATOMIC, &urb->transfer_dma);
|
|
||||||
#else
|
|
||||||
urb->transfer_buffer = usb_alloc_coherent(psIntfAdapter->udev, len,
|
urb->transfer_buffer = usb_alloc_coherent(psIntfAdapter->udev, len,
|
||||||
GFP_ATOMIC, &urb->transfer_dma);
|
GFP_ATOMIC, &urb->transfer_dma);
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!urb->transfer_buffer)
|
if (!urb->transfer_buffer)
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Error allocating memory\n");
|
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Error allocating memory\n");
|
||||||
@ -255,5 +194,4 @@ int InterfaceTransmitPacket(PVOID arg, PVOID data, UINT len)
|
|||||||
return TransmitTcb(psIntfAdapter, pTcb, data, len);
|
return TransmitTcb(psIntfAdapter, pTcb, data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
@ -3,11 +3,5 @@
|
|||||||
|
|
||||||
INT InterfaceTransmitPacket(PVOID arg, PVOID data, UINT len);
|
INT InterfaceTransmitPacket(PVOID arg, PVOID data, UINT len);
|
||||||
|
|
||||||
|
|
||||||
ULONG InterfaceTxDataPacket(PMINI_ADAPTER Adapter,PVOID Packet,USHORT usVcid);
|
|
||||||
|
|
||||||
ULONG InterfaceTxControlPacket(PMINI_ADAPTER Adapter,PVOID pvBuffer,UINT uiBufferLength);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
#ifndef _MAIN_
|
|
||||||
#define _MAIN_
|
|
||||||
#if 0
|
|
||||||
typedef struct _MINI_ADAPTER
|
|
||||||
{
|
|
||||||
S_INTERFACE_ADAPTER stInterfaceAdapter;
|
|
||||||
}MINI_ADAPTER,*PMINI_ADAPTER;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif
|
|
@ -75,14 +75,14 @@ static VOID UpdateTokenCount(register PMINI_ADAPTER Adapter)
|
|||||||
* Returns - The number of bytes allowed for transmission.
|
* Returns - The number of bytes allowed for transmission.
|
||||||
*
|
*
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
static __inline ULONG GetSFTokenCount(PMINI_ADAPTER Adapter, PacketInfo *psSF)
|
static ULONG GetSFTokenCount(PMINI_ADAPTER Adapter, PacketInfo *psSF)
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IsPacketAllowedForFlow ===>");
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IsPacketAllowedForFlow ===>");
|
||||||
/* Validate the parameters */
|
/* Validate the parameters */
|
||||||
if(NULL == Adapter || (psSF < Adapter->PackInfo &&
|
if(NULL == Adapter || (psSF < Adapter->PackInfo &&
|
||||||
(uintptr_t)psSF > (uintptr_t) &Adapter->PackInfo[HiPriority]))
|
(uintptr_t)psSF > (uintptr_t) &Adapter->PackInfo[HiPriority]))
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IPAFF: Got wrong Parameters:Adapter: %p, QIndex: %ld\n", Adapter, (psSF-Adapter->PackInfo));
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IPAFF: Got wrong Parameters:Adapter: %p, QIndex: %zd\n", Adapter, (psSF-Adapter->PackInfo));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,51 +94,27 @@ static __inline ULONG GetSFTokenCount(PMINI_ADAPTER Adapter, PacketInfo *psSF)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "Not enough tokens in queue %ld Available %u\n",
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "Not enough tokens in queue %zd Available %u\n",
|
||||||
psSF-Adapter->PackInfo, psSF->uiCurrentTokenCount);
|
psSF-Adapter->PackInfo, psSF->uiCurrentTokenCount);
|
||||||
psSF->uiPendedLast = 1;
|
psSF->uiPendedLast = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IPAFF: Queue %ld not valid\n", psSF-Adapter->PackInfo);
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IPAFF: Queue %zd not valid\n", psSF-Adapter->PackInfo);
|
||||||
}
|
}
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IsPacketAllowedForFlow <===");
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IsPacketAllowedForFlow <===");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline void RemovePacketFromQueue(PacketInfo *pPackInfo , struct sk_buff *Packet)
|
|
||||||
{
|
|
||||||
struct sk_buff *psQueueCurrent=NULL, *psLastQueueNode=NULL;
|
|
||||||
psQueueCurrent = pPackInfo->FirstTxQueue;
|
|
||||||
while(psQueueCurrent)
|
|
||||||
{
|
|
||||||
if(Packet == psQueueCurrent)
|
|
||||||
{
|
|
||||||
if(psQueueCurrent == pPackInfo->FirstTxQueue)
|
|
||||||
{
|
|
||||||
pPackInfo->FirstTxQueue=psQueueCurrent->next;
|
|
||||||
if(psQueueCurrent==pPackInfo->LastTxQueue)
|
|
||||||
pPackInfo->LastTxQueue=NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
psLastQueueNode->next=psQueueCurrent->next;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
psLastQueueNode = psQueueCurrent;
|
|
||||||
psQueueCurrent=psQueueCurrent->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
@ingroup tx_functions
|
@ingroup tx_functions
|
||||||
This function despatches packet from the specified queue.
|
This function despatches packet from the specified queue.
|
||||||
@return Zero(success) or Negative value(failure)
|
@return Zero(success) or Negative value(failure)
|
||||||
*/
|
*/
|
||||||
static __inline INT SendPacketFromQueue(PMINI_ADAPTER Adapter,/**<Logical Adapter*/
|
static INT SendPacketFromQueue(PMINI_ADAPTER Adapter,/**<Logical Adapter*/
|
||||||
PacketInfo *psSF, /**<Queue identifier*/
|
PacketInfo *psSF, /**<Queue identifier*/
|
||||||
struct sk_buff* Packet) /**<Pointer to the packet to be sent*/
|
struct sk_buff* Packet) /**<Pointer to the packet to be sent*/
|
||||||
{
|
{
|
||||||
INT Status=STATUS_FAILURE;
|
INT Status=STATUS_FAILURE;
|
||||||
UINT uiIndex =0,PktLen = 0;
|
UINT uiIndex =0,PktLen = 0;
|
||||||
@ -180,8 +156,7 @@ static __inline INT SendPacketFromQueue(PMINI_ADAPTER Adapter,/**<Logical Adapte
|
|||||||
* Returns - None.
|
* Returns - None.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static __inline VOID CheckAndSendPacketFromIndex
|
static VOID CheckAndSendPacketFromIndex(PMINI_ADAPTER Adapter, PacketInfo *psSF)
|
||||||
(PMINI_ADAPTER Adapter, PacketInfo *psSF)
|
|
||||||
{
|
{
|
||||||
struct sk_buff *QueuePacket=NULL;
|
struct sk_buff *QueuePacket=NULL;
|
||||||
char *pControlPacket = NULL;
|
char *pControlPacket = NULL;
|
||||||
@ -189,7 +164,7 @@ static __inline VOID CheckAndSendPacketFromIndex
|
|||||||
int iPacketLen=0;
|
int iPacketLen=0;
|
||||||
|
|
||||||
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "%ld ====>", (psSF-Adapter->PackInfo));
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "%zd ====>", (psSF-Adapter->PackInfo));
|
||||||
if((psSF != &Adapter->PackInfo[HiPriority]) && Adapter->LinkUpStatus && atomic_read(&psSF->uiPerSFTxResourceCount))//Get data packet
|
if((psSF != &Adapter->PackInfo[HiPriority]) && Adapter->LinkUpStatus && atomic_read(&psSF->uiPerSFTxResourceCount))//Get data packet
|
||||||
{
|
{
|
||||||
if(!psSF->ucDirection )
|
if(!psSF->ucDirection )
|
||||||
@ -197,10 +172,8 @@ static __inline VOID CheckAndSendPacketFromIndex
|
|||||||
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "UpdateTokenCount ");
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "UpdateTokenCount ");
|
||||||
if(Adapter->IdleMode || Adapter->bPreparingForLowPowerMode)
|
if(Adapter->IdleMode || Adapter->bPreparingForLowPowerMode)
|
||||||
{
|
return; /* in idle mode */
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Device is in Idle Mode..Hence blocking Data Packets..\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Check for Free Descriptors
|
// Check for Free Descriptors
|
||||||
if(atomic_read(&Adapter->CurrNumFreeTxDesc) <= MINIMUM_PENDING_DESCRIPTORS)
|
if(atomic_read(&Adapter->CurrNumFreeTxDesc) <= MINIMUM_PENDING_DESCRIPTORS)
|
||||||
{
|
{
|
||||||
@ -208,9 +181,6 @@ static __inline VOID CheckAndSendPacketFromIndex
|
|||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
PruneQueue(Adapter,(psSF-Adapter->PackInfo));
|
|
||||||
#endif
|
|
||||||
spin_lock_bh(&psSF->SFQueueLock);
|
spin_lock_bh(&psSF->SFQueueLock);
|
||||||
QueuePacket=psSF->FirstTxQueue;
|
QueuePacket=psSF->FirstTxQueue;
|
||||||
|
|
||||||
@ -240,7 +210,7 @@ static __inline VOID CheckAndSendPacketFromIndex
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "For Queue: %ld\n", psSF-Adapter->PackInfo);
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "For Queue: %zd\n", psSF-Adapter->PackInfo);
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "\nAvailable Tokens = %d required = %d\n",
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "\nAvailable Tokens = %d required = %d\n",
|
||||||
psSF->uiCurrentTokenCount, iPacketLen);
|
psSF->uiCurrentTokenCount, iPacketLen);
|
||||||
//this part indicates that becuase of non-availability of the tokens
|
//this part indicates that becuase of non-availability of the tokens
|
||||||
@ -290,17 +260,6 @@ static __inline VOID CheckAndSendPacketFromIndex
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Status != STATUS_SUCCESS) //Tx of data packet to device Failed
|
|
||||||
{
|
|
||||||
if(Adapter->bcm_jiffies == 0)
|
|
||||||
Adapter->bcm_jiffies = jiffies;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Adapter->bcm_jiffies = 0;
|
|
||||||
}
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "<=====");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -387,12 +346,7 @@ VOID transmit_packets(PMINI_ADAPTER Adapter)
|
|||||||
if(exit_flag == TRUE )
|
if(exit_flag == TRUE )
|
||||||
break ;
|
break ;
|
||||||
}/* end of inner while loop */
|
}/* end of inner while loop */
|
||||||
if(Adapter->bcm_jiffies == 0 &&
|
|
||||||
atomic_read(&Adapter->TotalPacketCount) != 0 &&
|
|
||||||
uiPrevTotalCount == atomic_read(&Adapter->TotalPacketCount))
|
|
||||||
{
|
|
||||||
Adapter->bcm_jiffies = jiffies;
|
|
||||||
}
|
|
||||||
update_per_cid_rx (Adapter);
|
update_per_cid_rx (Adapter);
|
||||||
Adapter->txtransmit_running = 0;
|
Adapter->txtransmit_running = 0;
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "<======");
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "<======");
|
||||||
|
@ -4,10 +4,6 @@
|
|||||||
#ifndef __MACROS_H__
|
#ifndef __MACROS_H__
|
||||||
#define __MACROS_H__
|
#define __MACROS_H__
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
|
|
||||||
#define kthread_run(threadfn,data,datafmt)(struct task_struct *)kernel_thread(threadfn,data,0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define TX_TIMER_PERIOD 10 //10 msec
|
#define TX_TIMER_PERIOD 10 //10 msec
|
||||||
#define MAX_CLASSIFIERS 100
|
#define MAX_CLASSIFIERS 100
|
||||||
//#define MAX_CLASSIFIERS_PER_SF 20
|
//#define MAX_CLASSIFIERS_PER_SF 20
|
||||||
@ -17,10 +13,9 @@
|
|||||||
#define MAX_DATA_PKTS 200
|
#define MAX_DATA_PKTS 200
|
||||||
#define MAX_ETH_SIZE 1536
|
#define MAX_ETH_SIZE 1536
|
||||||
#define MAX_CNTL_PKT_SIZE 2048
|
#define MAX_CNTL_PKT_SIZE 2048
|
||||||
/* TIMER RELATED */
|
|
||||||
#define JIFFIES_2_QUADPART() (ULONG)(jiffies * 10000) // jiffies(1msec) to Quadpart(100nsec)
|
|
||||||
|
|
||||||
#define MTU_SIZE 1400
|
#define MTU_SIZE 1400
|
||||||
|
#define TX_QLEN 5
|
||||||
|
|
||||||
#define MAC_ADDR_REGISTER 0xbf60d000
|
#define MAC_ADDR_REGISTER 0xbf60d000
|
||||||
|
|
||||||
@ -266,7 +261,7 @@ typedef enum _E_PHS_DSC_ACTION
|
|||||||
|
|
||||||
#define FIRMWARE_BEGIN_ADDR 0xBFC00000
|
#define FIRMWARE_BEGIN_ADDR 0xBFC00000
|
||||||
|
|
||||||
#define INVALID_QUEUE_INDEX (USHORT)-1
|
#define INVALID_QUEUE_INDEX NO_OF_QUEUES
|
||||||
|
|
||||||
#define INVALID_PID (pid_t)-1
|
#define INVALID_PID (pid_t)-1
|
||||||
#define DDR_80_MHZ 0
|
#define DDR_80_MHZ 0
|
||||||
@ -300,12 +295,7 @@ typedef enum _E_PHS_DSC_ACTION
|
|||||||
|
|
||||||
/* Idle Mode Related Registers */
|
/* Idle Mode Related Registers */
|
||||||
#define DEBUG_INTERRUPT_GENERATOR_REGISTOR 0x0F00007C
|
#define DEBUG_INTERRUPT_GENERATOR_REGISTOR 0x0F00007C
|
||||||
#ifdef BCM_SHM_INTERFACE
|
|
||||||
#define SW_ABORT_IDLEMODE_LOC 0xbfc02f9c
|
|
||||||
#define CPE_VIRTUAL_MAILBOX_REG 0xBFC02E58
|
|
||||||
#else
|
|
||||||
#define SW_ABORT_IDLEMODE_LOC 0x0FF01FFC
|
#define SW_ABORT_IDLEMODE_LOC 0x0FF01FFC
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SW_ABORT_IDLEMODE_PATTERN 0xd0ea1d1e
|
#define SW_ABORT_IDLEMODE_PATTERN 0xd0ea1d1e
|
||||||
#define DEVICE_INT_OUT_EP_REG0 0x0F011870
|
#define DEVICE_INT_OUT_EP_REG0 0x0F011870
|
||||||
@ -355,12 +345,7 @@ typedef enum ePMU_MODES
|
|||||||
HYBRID_MODE_6 = 2
|
HYBRID_MODE_6 = 2
|
||||||
}PMU_MODE;
|
}PMU_MODE;
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)
|
|
||||||
#define MAX_RDM_WRM_RETIRES 16
|
|
||||||
#else
|
|
||||||
#define MAX_RDM_WRM_RETIRES 1
|
#define MAX_RDM_WRM_RETIRES 1
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
enum eAbortPattern {
|
enum eAbortPattern {
|
||||||
ABORT_SHUTDOWN_MODE = 1,
|
ABORT_SHUTDOWN_MODE = 1,
|
||||||
@ -369,27 +354,6 @@ enum eAbortPattern {
|
|||||||
ABORT_IDLE_SYNCDOWN = 3
|
ABORT_IDLE_SYNCDOWN = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
|
|
||||||
#define GET_BCM_ADAPTER(net_dev) ({\
|
|
||||||
PMINI_ADAPTER __Adapter = NULL; \
|
|
||||||
if (net_dev) { \
|
|
||||||
__Adapter = (PMINI_ADAPTER)(net_dev->priv); \
|
|
||||||
} \
|
|
||||||
else { \
|
|
||||||
__Adapter = NULL; \
|
|
||||||
}__Adapter;} )
|
|
||||||
#else
|
|
||||||
#define GET_BCM_ADAPTER(net_dev) ({\
|
|
||||||
PMINI_ADAPTER __Adapter = NULL; \
|
|
||||||
if (net_dev) { \
|
|
||||||
__Adapter = (PMINI_ADAPTER)(*((unsigned long *)netdev_priv(net_dev))); \
|
|
||||||
} \
|
|
||||||
else { \
|
|
||||||
__Adapter = NULL; \
|
|
||||||
}__Adapter;})
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Offsets used by driver in skb cb variable */
|
/* Offsets used by driver in skb cb variable */
|
||||||
#define SKB_CB_CLASSIFICATION_OFFSET 0
|
#define SKB_CB_CLASSIFICATION_OFFSET 0
|
||||||
|
@ -6,7 +6,7 @@ obj-$(CONFIG_BCM_WIMAX) += bcm_wimax.o
|
|||||||
|
|
||||||
bcm_wimax-y := InterfaceDld.o InterfaceIdleMode.o InterfaceInit.o InterfaceRx.o \
|
bcm_wimax-y := InterfaceDld.o InterfaceIdleMode.o InterfaceInit.o InterfaceRx.o \
|
||||||
InterfaceIsr.o InterfaceMisc.o InterfaceTx.o \
|
InterfaceIsr.o InterfaceMisc.o InterfaceTx.o \
|
||||||
Arp.o CmHost.o Debug.o IPv6Protocol.o Qos.o Transmit.o\
|
CmHost.o IPv6Protocol.o Qos.o Transmit.o\
|
||||||
Bcmnet.o DDRInit.o HandleControlPacket.o\
|
Bcmnet.o DDRInit.o HandleControlPacket.o\
|
||||||
LeakyBucket.o Misc.o sort.o Bcmchar.o hostmibs.o PHSModule.o\
|
LeakyBucket.o Misc.o sort.o Bcmchar.o hostmibs.o PHSModule.o\
|
||||||
Osal_Misc.o led_control.o nvm.o vendorspecificextn.o
|
led_control.o nvm.o vendorspecificextn.o
|
||||||
|
@ -1,5 +1,12 @@
|
|||||||
#include "headers.h"
|
#include "headers.h"
|
||||||
|
|
||||||
|
static int BcmFileDownload(PMINI_ADAPTER Adapter, const char *path,
|
||||||
|
unsigned int loc);
|
||||||
|
static VOID doPowerAutoCorrection(PMINI_ADAPTER psAdapter);
|
||||||
|
static void HandleShutDownModeRequest(PMINI_ADAPTER Adapter,PUCHAR pucBuffer);
|
||||||
|
static int bcm_parse_target_params(PMINI_ADAPTER Adapter);
|
||||||
|
static void beceem_protocol_reset (PMINI_ADAPTER Adapter);
|
||||||
|
|
||||||
static VOID default_wimax_protocol_initialize(PMINI_ADAPTER Adapter)
|
static VOID default_wimax_protocol_initialize(PMINI_ADAPTER Adapter)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -60,21 +67,11 @@ InitAdapter(PMINI_ADAPTER psAdapter)
|
|||||||
//init_waitqueue_head(&psAdapter->device_wake_queue);
|
//init_waitqueue_head(&psAdapter->device_wake_queue);
|
||||||
psAdapter->fw_download_done=FALSE;
|
psAdapter->fw_download_done=FALSE;
|
||||||
|
|
||||||
psAdapter->pvOsDepData = (PLINUX_DEP_DATA) kmalloc(sizeof(LINUX_DEP_DATA),
|
|
||||||
GFP_KERNEL);
|
|
||||||
|
|
||||||
if(psAdapter->pvOsDepData == NULL)
|
|
||||||
{
|
|
||||||
BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Linux Specific Data allocation failed");
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
memset(psAdapter->pvOsDepData, 0, sizeof(LINUX_DEP_DATA));
|
|
||||||
|
|
||||||
default_wimax_protocol_initialize(psAdapter);
|
default_wimax_protocol_initialize(psAdapter);
|
||||||
for (i=0;i<MAX_CNTRL_PKTS;i++)
|
for (i=0;i<MAX_CNTRL_PKTS;i++)
|
||||||
{
|
{
|
||||||
psAdapter->txctlpacket[i] = (char *)kmalloc(MAX_CNTL_PKT_SIZE,
|
psAdapter->txctlpacket[i] = kmalloc(MAX_CNTL_PKT_SIZE, GFP_KERNEL);
|
||||||
GFP_KERNEL);
|
|
||||||
if(!psAdapter->txctlpacket[i])
|
if(!psAdapter->txctlpacket[i])
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "No More Cntl pkts got, max got is %d", i);
|
BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "No More Cntl pkts got, max got is %d", i);
|
||||||
@ -117,7 +114,7 @@ InitAdapter(PMINI_ADAPTER psAdapter)
|
|||||||
|
|
||||||
VOID AdapterFree(PMINI_ADAPTER Adapter)
|
VOID AdapterFree(PMINI_ADAPTER Adapter)
|
||||||
{
|
{
|
||||||
INT count = 0;
|
int count;
|
||||||
|
|
||||||
beceem_protocol_reset(Adapter);
|
beceem_protocol_reset(Adapter);
|
||||||
|
|
||||||
@ -125,72 +122,66 @@ VOID AdapterFree(PMINI_ADAPTER Adapter)
|
|||||||
|
|
||||||
if(Adapter->control_packet_handler && !IS_ERR(Adapter->control_packet_handler))
|
if(Adapter->control_packet_handler && !IS_ERR(Adapter->control_packet_handler))
|
||||||
kthread_stop (Adapter->control_packet_handler);
|
kthread_stop (Adapter->control_packet_handler);
|
||||||
|
|
||||||
if(Adapter->transmit_packet_thread && !IS_ERR(Adapter->transmit_packet_thread))
|
if(Adapter->transmit_packet_thread && !IS_ERR(Adapter->transmit_packet_thread))
|
||||||
kthread_stop (Adapter->transmit_packet_thread);
|
kthread_stop (Adapter->transmit_packet_thread);
|
||||||
wake_up(&Adapter->process_read_wait_queue);
|
|
||||||
|
wake_up(&Adapter->process_read_wait_queue);
|
||||||
|
|
||||||
if(Adapter->LEDInfo.led_thread_running & (BCM_LED_THREAD_RUNNING_ACTIVELY | BCM_LED_THREAD_RUNNING_INACTIVELY))
|
if(Adapter->LEDInfo.led_thread_running & (BCM_LED_THREAD_RUNNING_ACTIVELY | BCM_LED_THREAD_RUNNING_INACTIVELY))
|
||||||
kthread_stop (Adapter->LEDInfo.led_cntrl_threadid);
|
kthread_stop (Adapter->LEDInfo.led_cntrl_threadid);
|
||||||
bcm_unregister_networkdev(Adapter);
|
|
||||||
|
unregister_networkdev(Adapter);
|
||||||
|
|
||||||
|
/* FIXME: use proper wait_event and refcounting */
|
||||||
while(atomic_read(&Adapter->ApplicationRunning))
|
while(atomic_read(&Adapter->ApplicationRunning))
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Waiting for Application to close.. %d\n",atomic_read(&Adapter->ApplicationRunning));
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Waiting for Application to close.. %d\n",atomic_read(&Adapter->ApplicationRunning));
|
||||||
msleep(100);
|
msleep(100);
|
||||||
}
|
}
|
||||||
unregister_control_device_interface(Adapter);
|
unregister_control_device_interface(Adapter);
|
||||||
if(Adapter->dev && !IS_ERR(Adapter->dev))
|
|
||||||
free_netdev(Adapter->dev);
|
kfree(Adapter->pstargetparams);
|
||||||
if(Adapter->pstargetparams != NULL)
|
|
||||||
{
|
|
||||||
bcm_kfree(Adapter->pstargetparams);
|
|
||||||
}
|
|
||||||
for (count =0;count < MAX_CNTRL_PKTS;count++)
|
for (count =0;count < MAX_CNTRL_PKTS;count++)
|
||||||
{
|
kfree(Adapter->txctlpacket[count]);
|
||||||
if(Adapter->txctlpacket[count])
|
|
||||||
bcm_kfree(Adapter->txctlpacket[count]);
|
|
||||||
}
|
|
||||||
FreeAdapterDsxBuffer(Adapter);
|
FreeAdapterDsxBuffer(Adapter);
|
||||||
if(Adapter->pvOsDepData)
|
|
||||||
bcm_kfree (Adapter->pvOsDepData);
|
kfree(Adapter->pvInterfaceAdapter);
|
||||||
if(Adapter->pvInterfaceAdapter)
|
|
||||||
bcm_kfree(Adapter->pvInterfaceAdapter);
|
|
||||||
|
|
||||||
//Free the PHS Interface
|
//Free the PHS Interface
|
||||||
PhsCleanup(&Adapter->stBCMPhsContext);
|
PhsCleanup(&Adapter->stBCMPhsContext);
|
||||||
|
|
||||||
#ifndef BCM_SHM_INTERFACE
|
|
||||||
BcmDeAllocFlashCSStructure(Adapter);
|
BcmDeAllocFlashCSStructure(Adapter);
|
||||||
#endif
|
|
||||||
|
|
||||||
bcm_kfree (Adapter);
|
free_netdev(Adapter->dev);
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "<========\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int create_worker_threads(PMINI_ADAPTER psAdapter)
|
||||||
int create_worker_threads(PMINI_ADAPTER psAdapter)
|
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Init Threads...");
|
|
||||||
// Rx Control Packets Processing
|
// Rx Control Packets Processing
|
||||||
psAdapter->control_packet_handler = kthread_run((int (*)(void *))
|
psAdapter->control_packet_handler = kthread_run((int (*)(void *))
|
||||||
control_packet_handler, psAdapter, "CtrlPktHdlr");
|
control_packet_handler, psAdapter, "%s-rx", DRV_NAME);
|
||||||
if(IS_ERR(psAdapter->control_packet_handler))
|
if(IS_ERR(psAdapter->control_packet_handler))
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "No Kernel Thread, but still returning success\n");
|
pr_notice(DRV_NAME ": could not create control thread\n");
|
||||||
return PTR_ERR(psAdapter->control_packet_handler);
|
return PTR_ERR(psAdapter->control_packet_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tx Thread
|
// Tx Thread
|
||||||
psAdapter->transmit_packet_thread = kthread_run((int (*)(void *))
|
psAdapter->transmit_packet_thread = kthread_run((int (*)(void *))
|
||||||
tx_pkt_handler, psAdapter, "TxPktThread");
|
tx_pkt_handler, psAdapter, "%s-tx", DRV_NAME);
|
||||||
if(IS_ERR (psAdapter->transmit_packet_thread))
|
if(IS_ERR (psAdapter->transmit_packet_thread))
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "No Kernel Thread, but still returning success");
|
pr_notice(DRV_NAME ": could not creat transmit thread\n");
|
||||||
kthread_stop(psAdapter->control_packet_handler);
|
kthread_stop(psAdapter->control_packet_handler);
|
||||||
return PTR_ERR(psAdapter->transmit_packet_thread);
|
return PTR_ERR(psAdapter->transmit_packet_thread);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct file *open_firmware_file(PMINI_ADAPTER Adapter, const char *path)
|
||||||
static inline struct file *open_firmware_file(PMINI_ADAPTER Adapter, char *path)
|
|
||||||
{
|
{
|
||||||
struct file *flp=NULL;
|
struct file *flp=NULL;
|
||||||
mm_segment_t oldfs;
|
mm_segment_t oldfs;
|
||||||
@ -200,26 +191,20 @@ static inline struct file *open_firmware_file(PMINI_ADAPTER Adapter, char *path)
|
|||||||
set_fs(oldfs);
|
set_fs(oldfs);
|
||||||
if(IS_ERR(flp))
|
if(IS_ERR(flp))
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Unable To Open File %s, err %lx",
|
pr_err(DRV_NAME "Unable To Open File %s, err %ld",
|
||||||
path, PTR_ERR(flp));
|
path, PTR_ERR(flp));
|
||||||
flp = NULL;
|
flp = NULL;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
if(Adapter->device_removed)
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Got file descriptor pointer of %s!",
|
flp = NULL;
|
||||||
path);
|
|
||||||
}
|
|
||||||
if(Adapter->device_removed)
|
|
||||||
{
|
|
||||||
flp = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return flp;
|
return flp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int BcmFileDownload(PMINI_ADAPTER Adapter,/**< Logical Adapter */
|
static int BcmFileDownload(PMINI_ADAPTER Adapter,/**< Logical Adapter */
|
||||||
char *path, /**< path to image file */
|
const char *path, /**< path to image file */
|
||||||
unsigned int loc /**< Download Address on the chip*/
|
unsigned int loc /**< Download Address on the chip*/
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@ -248,9 +233,7 @@ int BcmFileDownload(PMINI_ADAPTER Adapter,/**< Logical Adapter */
|
|||||||
goto exit_download;
|
goto exit_download;
|
||||||
}
|
}
|
||||||
oldfs=get_fs();set_fs(get_ds());
|
oldfs=get_fs();set_fs(get_ds());
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
|
||||||
vfs_llseek(flp, 0, 0);
|
vfs_llseek(flp, 0, 0);
|
||||||
#endif
|
|
||||||
set_fs(oldfs);
|
set_fs(oldfs);
|
||||||
if(Adapter->bcm_file_readback_from_chip(Adapter->pvInterfaceAdapter,
|
if(Adapter->bcm_file_readback_from_chip(Adapter->pvInterfaceAdapter,
|
||||||
flp, loc))
|
flp, loc))
|
||||||
@ -265,31 +248,10 @@ int BcmFileDownload(PMINI_ADAPTER Adapter,/**< Logical Adapter */
|
|||||||
if(flp && !(IS_ERR(flp)))
|
if(flp && !(IS_ERR(flp)))
|
||||||
filp_close(flp, current->files);
|
filp_close(flp, current->files);
|
||||||
set_fs(oldfs);
|
set_fs(oldfs);
|
||||||
do_gettimeofday(&tv);
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "file download done at %lx", ((tv.tv_sec * 1000) +
|
|
||||||
(tv.tv_usec/1000)));
|
|
||||||
return errorno;
|
return errorno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void bcm_kfree_skb(struct sk_buff *skb)
|
|
||||||
{
|
|
||||||
if(skb)
|
|
||||||
{
|
|
||||||
kfree_skb(skb);
|
|
||||||
}
|
|
||||||
skb = NULL ;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID bcm_kfree(VOID *ptr)
|
|
||||||
{
|
|
||||||
if(ptr)
|
|
||||||
{
|
|
||||||
kfree(ptr);
|
|
||||||
}
|
|
||||||
ptr = NULL ;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ingroup ctrl_pkt_functions
|
@ingroup ctrl_pkt_functions
|
||||||
This function copies the contents of given buffer
|
This function copies the contents of given buffer
|
||||||
@ -395,13 +357,6 @@ INT CopyBufferToControlPacket(PMINI_ADAPTER Adapter,/**<Logical Adapter*/
|
|||||||
/*Setting bIdleMode_tx_from_host to TRUE to indicate LED control thread to represent
|
/*Setting bIdleMode_tx_from_host to TRUE to indicate LED control thread to represent
|
||||||
the wake up from idlemode is from host*/
|
the wake up from idlemode is from host*/
|
||||||
//Adapter->LEDInfo.bIdleMode_tx_from_host = TRUE;
|
//Adapter->LEDInfo.bIdleMode_tx_from_host = TRUE;
|
||||||
#if 0
|
|
||||||
if(STATUS_SUCCESS != InterfaceIdleModeWakeup(Adapter))
|
|
||||||
{
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Idle Mode Wake up Failed\n");
|
|
||||||
return STATUS_FAILURE;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
Adapter->bWakeUpDevice = TRUE;
|
Adapter->bWakeUpDevice = TRUE;
|
||||||
wake_up(&Adapter->process_rx_cntrlpkt);
|
wake_up(&Adapter->process_rx_cntrlpkt);
|
||||||
|
|
||||||
@ -489,9 +444,6 @@ INT CopyBufferToControlPacket(PMINI_ADAPTER Adapter,/**<Logical Adapter*/
|
|||||||
atomic_inc(&Adapter->index_wr_txcntrlpkt);
|
atomic_inc(&Adapter->index_wr_txcntrlpkt);
|
||||||
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "Calling transmit_packets");
|
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "Calling transmit_packets");
|
||||||
atomic_set(&Adapter->TxPktAvail, 1);
|
atomic_set(&Adapter->TxPktAvail, 1);
|
||||||
#ifdef BCM_SHM_INTERFACE
|
|
||||||
virtual_mail_box_interrupt();
|
|
||||||
#endif
|
|
||||||
wake_up(&Adapter->tx_packet_wait_queue);
|
wake_up(&Adapter->tx_packet_wait_queue);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -530,18 +482,6 @@ static VOID SendStatisticsPointerRequest(PMINI_ADAPTER Adapter,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void SendLinkDown(PMINI_ADAPTER Adapter)
|
|
||||||
{
|
|
||||||
LINK_REQUEST stLinkDownRequest;
|
|
||||||
memset(&stLinkDownRequest, 0, sizeof(LINK_REQUEST));
|
|
||||||
stLinkDownRequest.Leader.Status=LINK_UP_CONTROL_REQ;
|
|
||||||
stLinkDownRequest.Leader.PLength=sizeof(ULONG);//minimum 4 bytes
|
|
||||||
stLinkDownRequest.szData[0]=LINK_DOWN_REQ_PAYLOAD;
|
|
||||||
Adapter->bLinkDownRequested = TRUE;
|
|
||||||
|
|
||||||
CopyBufferToControlPacket(Adapter,&stLinkDownRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
* Function - LinkMessage()
|
* Function - LinkMessage()
|
||||||
*
|
*
|
||||||
@ -552,7 +492,7 @@ void SendLinkDown(PMINI_ADAPTER Adapter)
|
|||||||
*
|
*
|
||||||
* Returns - None.
|
* Returns - None.
|
||||||
*******************************************************************/
|
*******************************************************************/
|
||||||
__inline VOID LinkMessage(PMINI_ADAPTER Adapter)
|
VOID LinkMessage(PMINI_ADAPTER Adapter)
|
||||||
{
|
{
|
||||||
PLINK_REQUEST pstLinkRequest=NULL;
|
PLINK_REQUEST pstLinkRequest=NULL;
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "=====>");
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "=====>");
|
||||||
@ -594,7 +534,7 @@ __inline VOID LinkMessage(PMINI_ADAPTER Adapter)
|
|||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Calling CopyBufferToControlPacket");
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Calling CopyBufferToControlPacket");
|
||||||
CopyBufferToControlPacket(Adapter, pstLinkRequest);
|
CopyBufferToControlPacket(Adapter, pstLinkRequest);
|
||||||
bcm_kfree(pstLinkRequest);
|
kfree(pstLinkRequest);
|
||||||
}
|
}
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "LinkMessage <=====");
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "LinkMessage <=====");
|
||||||
return;
|
return;
|
||||||
@ -614,8 +554,8 @@ __inline VOID LinkMessage(PMINI_ADAPTER Adapter)
|
|||||||
VOID StatisticsResponse(PMINI_ADAPTER Adapter,PVOID pvBuffer)
|
VOID StatisticsResponse(PMINI_ADAPTER Adapter,PVOID pvBuffer)
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "%s====>",__FUNCTION__);
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "%s====>",__FUNCTION__);
|
||||||
Adapter->StatisticsPointer = ntohl(*(PULONG)pvBuffer);
|
Adapter->StatisticsPointer = ntohl(*(__be32 *)pvBuffer);
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Stats at %lx", Adapter->StatisticsPointer);
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Stats at %x", (UINT)Adapter->StatisticsPointer);
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "%s <====",__FUNCTION__);
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "%s <====",__FUNCTION__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -764,7 +704,7 @@ void SendIdleModeResponse(PMINI_ADAPTER Adapter)
|
|||||||
|
|
||||||
/* Wake the LED Thread with IDLEMODE_ENTER State */
|
/* Wake the LED Thread with IDLEMODE_ENTER State */
|
||||||
Adapter->DriverState = LOWPOWER_MODE_ENTER;
|
Adapter->DriverState = LOWPOWER_MODE_ENTER;
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL,"LED Thread is Running..Hence Setting LED Event as IDLEMODE_ENTER jiffies:%ld",jiffies);;
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL,"LED Thread is Running..Hence Setting LED Event as IDLEMODE_ENTER jiffies:%ld",jiffies);
|
||||||
wake_up(&Adapter->LEDInfo.notify_led_event);
|
wake_up(&Adapter->LEDInfo.notify_led_event);
|
||||||
|
|
||||||
/* Wait for 1 SEC for LED to OFF */
|
/* Wait for 1 SEC for LED to OFF */
|
||||||
@ -787,12 +727,10 @@ void SendIdleModeResponse(PMINI_ADAPTER Adapter)
|
|||||||
down(&Adapter->rdmwrmsync);
|
down(&Adapter->rdmwrmsync);
|
||||||
Adapter->bPreparingForLowPowerMode = TRUE;
|
Adapter->bPreparingForLowPowerMode = TRUE;
|
||||||
up(&Adapter->rdmwrmsync);
|
up(&Adapter->rdmwrmsync);
|
||||||
#ifndef BCM_SHM_INTERFACE
|
|
||||||
//Killing all URBS.
|
//Killing all URBS.
|
||||||
if(Adapter->bDoSuspend == TRUE)
|
if(Adapter->bDoSuspend == TRUE)
|
||||||
Bcm_kill_all_URBs((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));
|
Bcm_kill_all_URBs((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -811,9 +749,7 @@ void SendIdleModeResponse(PMINI_ADAPTER Adapter)
|
|||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"fail to send the Idle mode Request \n");
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"fail to send the Idle mode Request \n");
|
||||||
Adapter->bPreparingForLowPowerMode = FALSE;
|
Adapter->bPreparingForLowPowerMode = FALSE;
|
||||||
#ifndef BCM_SHM_INTERFACE
|
|
||||||
StartInterruptUrb((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));
|
StartInterruptUrb((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
do_gettimeofday(&tv);
|
do_gettimeofday(&tv);
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "IdleMode Msg submitter to Q :%ld ms", tv.tv_sec *1000 + tv.tv_usec /1000);
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "IdleMode Msg submitter to Q :%ld ms", tv.tv_sec *1000 + tv.tv_usec /1000);
|
||||||
@ -980,12 +916,10 @@ VOID DumpPackInfo(PMINI_ADAPTER Adapter)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int reset_card_proc(PMINI_ADAPTER ps_adapter)
|
||||||
__inline int reset_card_proc(PMINI_ADAPTER ps_adapter)
|
|
||||||
{
|
{
|
||||||
int retval = STATUS_SUCCESS;
|
int retval = STATUS_SUCCESS;
|
||||||
|
|
||||||
#ifndef BCM_SHM_INTERFACE
|
|
||||||
PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
|
PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
|
||||||
PS_INTERFACE_ADAPTER psIntfAdapter = NULL;
|
PS_INTERFACE_ADAPTER psIntfAdapter = NULL;
|
||||||
unsigned int value = 0, uiResetValue = 0;
|
unsigned int value = 0, uiResetValue = 0;
|
||||||
@ -1006,11 +940,9 @@ __inline int reset_card_proc(PMINI_ADAPTER ps_adapter)
|
|||||||
wrmalt(ps_adapter, SYS_CFG, &value, sizeof(value));
|
wrmalt(ps_adapter, SYS_CFG, &value, sizeof(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef BCM_SHM_INTERFACE
|
|
||||||
//killing all submitted URBs.
|
//killing all submitted URBs.
|
||||||
psIntfAdapter->psAdapter->StopAllXaction = TRUE ;
|
psIntfAdapter->psAdapter->StopAllXaction = TRUE ;
|
||||||
Bcm_kill_all_URBs(psIntfAdapter);
|
Bcm_kill_all_URBs(psIntfAdapter);
|
||||||
#endif
|
|
||||||
/* Reset the UMA-B Device */
|
/* Reset the UMA-B Device */
|
||||||
if(ps_adapter->chip_id >= T3LPB)
|
if(ps_adapter->chip_id >= T3LPB)
|
||||||
{
|
{
|
||||||
@ -1111,11 +1043,10 @@ __inline int reset_card_proc(PMINI_ADAPTER ps_adapter)
|
|||||||
|
|
||||||
err_exit :
|
err_exit :
|
||||||
psIntfAdapter->psAdapter->StopAllXaction = FALSE ;
|
psIntfAdapter->psAdapter->StopAllXaction = FALSE ;
|
||||||
#endif
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
__inline int run_card_proc(PMINI_ADAPTER ps_adapter )
|
int run_card_proc(PMINI_ADAPTER ps_adapter )
|
||||||
{
|
{
|
||||||
unsigned int value=0;
|
unsigned int value=0;
|
||||||
{
|
{
|
||||||
@ -1146,21 +1077,17 @@ __inline int run_card_proc(PMINI_ADAPTER ps_adapter )
|
|||||||
int InitCardAndDownloadFirmware(PMINI_ADAPTER ps_adapter)
|
int InitCardAndDownloadFirmware(PMINI_ADAPTER ps_adapter)
|
||||||
{
|
{
|
||||||
|
|
||||||
UINT status = STATUS_SUCCESS;
|
int status;
|
||||||
UINT value = 0;
|
UINT value = 0;
|
||||||
#ifdef BCM_SHM_INTERFACE
|
|
||||||
unsigned char *pConfigFileAddr = (unsigned char *)CPE_MACXVI_CFG_ADDR;
|
|
||||||
#endif
|
|
||||||
/*
|
/*
|
||||||
* Create the threads first and then download the
|
* Create the threads first and then download the
|
||||||
* Firm/DDR Settings..
|
* Firm/DDR Settings..
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if((status = create_worker_threads(ps_adapter))<0)
|
status = create_worker_threads(ps_adapter);
|
||||||
{
|
if (status<0)
|
||||||
BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Cannot create thread");
|
|
||||||
return status;
|
return status;
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
* For Downloading the Firm, parse the cfg file first.
|
* For Downloading the Firm, parse the cfg file first.
|
||||||
*/
|
*/
|
||||||
@ -1169,7 +1096,6 @@ int InitCardAndDownloadFirmware(PMINI_ADAPTER ps_adapter)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef BCM_SHM_INTERFACE
|
|
||||||
if(ps_adapter->chip_id >= T3LPB)
|
if(ps_adapter->chip_id >= T3LPB)
|
||||||
{
|
{
|
||||||
rdmalt(ps_adapter, SYS_CFG, &value, sizeof (value));
|
rdmalt(ps_adapter, SYS_CFG, &value, sizeof (value));
|
||||||
@ -1187,7 +1113,7 @@ int InitCardAndDownloadFirmware(PMINI_ADAPTER ps_adapter)
|
|||||||
status = ddr_init(ps_adapter);
|
status = ddr_init(ps_adapter);
|
||||||
if(status)
|
if(status)
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT (ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "ddr_init Failed\n");
|
pr_err(DRV_NAME "ddr_init Failed\n");
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1201,7 +1127,6 @@ int InitCardAndDownloadFirmware(PMINI_ADAPTER ps_adapter)
|
|||||||
BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Error downloading CFG file");
|
BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Error downloading CFG file");
|
||||||
goto OUT;
|
goto OUT;
|
||||||
}
|
}
|
||||||
BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "CFG file downloaded");
|
|
||||||
|
|
||||||
if(register_networkdev(ps_adapter))
|
if(register_networkdev(ps_adapter))
|
||||||
{
|
{
|
||||||
@ -1266,12 +1191,6 @@ int InitCardAndDownloadFirmware(PMINI_ADAPTER ps_adapter)
|
|||||||
goto OUT;
|
goto OUT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
else if(psAdapter->eNVMType == NVM_EEPROM)
|
|
||||||
{
|
|
||||||
PropagateCalParamsFromEEPROMToMemory();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Download Firmare */
|
/* Download Firmare */
|
||||||
if ((status = BcmFileDownload( ps_adapter, BIN_FILE, FIRMWARE_BEGIN_ADDR)))
|
if ((status = BcmFileDownload( ps_adapter, BIN_FILE, FIRMWARE_BEGIN_ADDR)))
|
||||||
@ -1280,7 +1199,6 @@ int InitCardAndDownloadFirmware(PMINI_ADAPTER ps_adapter)
|
|||||||
goto OUT;
|
goto OUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "BIN file downloaded");
|
|
||||||
status = run_card_proc(ps_adapter);
|
status = run_card_proc(ps_adapter);
|
||||||
if(status)
|
if(status)
|
||||||
{
|
{
|
||||||
@ -1299,68 +1217,19 @@ int InitCardAndDownloadFirmware(PMINI_ADAPTER ps_adapter)
|
|||||||
wake_up(&ps_adapter->LEDInfo.notify_led_event);
|
wake_up(&ps_adapter->LEDInfo.notify_led_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
ps_adapter->bDDRInitDone = TRUE;
|
|
||||||
//Initializing the NVM.
|
|
||||||
BcmInitNVM(ps_adapter);
|
|
||||||
|
|
||||||
//Propagating the cal param from Flash to DDR
|
|
||||||
value = 0;
|
|
||||||
wrmalt(ps_adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value));
|
|
||||||
wrmalt(ps_adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value));
|
|
||||||
|
|
||||||
if(ps_adapter->eNVMType == NVM_FLASH)
|
|
||||||
{
|
|
||||||
status = PropagateCalParamsFromFlashToMemory(ps_adapter);
|
|
||||||
if(status)
|
|
||||||
{
|
|
||||||
printk("\nPropogation of Cal param from flash to DDR failed ..\n" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Copy config file param to DDR.
|
|
||||||
memcpy(pConfigFileAddr,ps_adapter->pstargetparams, sizeof(STARGETPARAMS));
|
|
||||||
|
|
||||||
if(register_networkdev(ps_adapter))
|
|
||||||
{
|
|
||||||
BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Register Netdevice failed. Cleanup needs to be performed.");
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status = InitLedSettings (ps_adapter);
|
|
||||||
if(status)
|
|
||||||
{
|
|
||||||
BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_PRINTK, 0, 0,"INIT LED FAILED\n");
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(register_control_device_interface(ps_adapter) < 0)
|
|
||||||
{
|
|
||||||
BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Register Control Device failed. Cleanup needs to be performed.");
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
ps_adapter->fw_download_done = TRUE;
|
|
||||||
#endif
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int bcm_parse_target_params(PMINI_ADAPTER Adapter)
|
static int bcm_parse_target_params(PMINI_ADAPTER Adapter)
|
||||||
{
|
{
|
||||||
#ifdef BCM_SHM_INTERFACE
|
|
||||||
extern void read_cfg_file(PMINI_ADAPTER Adapter);
|
|
||||||
#endif
|
|
||||||
struct file *flp=NULL;
|
struct file *flp=NULL;
|
||||||
mm_segment_t oldfs={0};
|
mm_segment_t oldfs={0};
|
||||||
char *buff = NULL;
|
char *buff;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
loff_t pos = 0;
|
loff_t pos = 0;
|
||||||
|
|
||||||
buff=(PCHAR)kmalloc(BUFFER_1K, GFP_KERNEL);
|
buff=kmalloc(BUFFER_1K, GFP_KERNEL);
|
||||||
if(!buff)
|
if(!buff)
|
||||||
{
|
{
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@ -1368,14 +1237,14 @@ int bcm_parse_target_params(PMINI_ADAPTER Adapter)
|
|||||||
if((Adapter->pstargetparams =
|
if((Adapter->pstargetparams =
|
||||||
kmalloc(sizeof(STARGETPARAMS), GFP_KERNEL)) == NULL)
|
kmalloc(sizeof(STARGETPARAMS), GFP_KERNEL)) == NULL)
|
||||||
{
|
{
|
||||||
bcm_kfree(buff);
|
kfree(buff);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
flp=open_firmware_file(Adapter, CFG_FILE);
|
flp=open_firmware_file(Adapter, CFG_FILE);
|
||||||
if(!flp) {
|
if(!flp) {
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "NOT ABLE TO OPEN THE %s FILE \n", CFG_FILE);
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "NOT ABLE TO OPEN THE %s FILE \n", CFG_FILE);
|
||||||
bcm_kfree(buff);
|
kfree(buff);
|
||||||
bcm_kfree(Adapter->pstargetparams);
|
kfree(Adapter->pstargetparams);
|
||||||
Adapter->pstargetparams = NULL;
|
Adapter->pstargetparams = NULL;
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
@ -1386,8 +1255,8 @@ int bcm_parse_target_params(PMINI_ADAPTER Adapter)
|
|||||||
if(len != sizeof(STARGETPARAMS))
|
if(len != sizeof(STARGETPARAMS))
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Mismatch in Target Param Structure!\n");
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Mismatch in Target Param Structure!\n");
|
||||||
bcm_kfree(buff);
|
kfree(buff);
|
||||||
bcm_kfree(Adapter->pstargetparams);
|
kfree(Adapter->pstargetparams);
|
||||||
Adapter->pstargetparams = NULL;
|
Adapter->pstargetparams = NULL;
|
||||||
filp_close(flp, current->files);
|
filp_close(flp, current->files);
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
@ -1399,37 +1268,34 @@ int bcm_parse_target_params(PMINI_ADAPTER Adapter)
|
|||||||
* Values in Adapter->pstargetparams are in network byte order
|
* Values in Adapter->pstargetparams are in network byte order
|
||||||
*/
|
*/
|
||||||
memcpy(Adapter->pstargetparams, buff, sizeof(STARGETPARAMS));
|
memcpy(Adapter->pstargetparams, buff, sizeof(STARGETPARAMS));
|
||||||
bcm_kfree (buff);
|
kfree (buff);
|
||||||
beceem_parse_target_struct(Adapter);
|
beceem_parse_target_struct(Adapter);
|
||||||
#ifdef BCM_SHM_INTERFACE
|
|
||||||
read_cfg_file(Adapter);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void beceem_parse_target_struct(PMINI_ADAPTER Adapter)
|
void beceem_parse_target_struct(PMINI_ADAPTER Adapter)
|
||||||
{
|
{
|
||||||
UINT uiHostDrvrCfg6 =0, uiEEPROMFlag = 0;;
|
UINT uiHostDrvrCfg6 =0, uiEEPROMFlag = 0;
|
||||||
|
|
||||||
if(ntohl(Adapter->pstargetparams->m_u32PhyParameter2) & AUTO_SYNC_DISABLE)
|
if(ntohl(Adapter->pstargetparams->m_u32PhyParameter2) & AUTO_SYNC_DISABLE)
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "AutoSyncup is Disabled\n");
|
pr_info(DRV_NAME ": AutoSyncup is Disabled\n");
|
||||||
Adapter->AutoSyncup = FALSE;
|
Adapter->AutoSyncup = FALSE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "AutoSyncup is Enabled\n");
|
pr_info(DRV_NAME ": AutoSyncup is Enabled\n");
|
||||||
Adapter->AutoSyncup = TRUE;
|
Adapter->AutoSyncup = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ntohl(Adapter->pstargetparams->HostDrvrConfig6) & AUTO_LINKUP_ENABLE)
|
if(ntohl(Adapter->pstargetparams->HostDrvrConfig6) & AUTO_LINKUP_ENABLE)
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Enabling autolink up");
|
pr_info(DRV_NAME ": Enabling autolink up");
|
||||||
Adapter->AutoLinkUp = TRUE;
|
Adapter->AutoLinkUp = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Disabling autolink up");
|
pr_info(DRV_NAME ": Disabling autolink up");
|
||||||
Adapter->AutoLinkUp = FALSE;
|
Adapter->AutoLinkUp = FALSE;
|
||||||
}
|
}
|
||||||
// Setting the DDR Setting..
|
// Setting the DDR Setting..
|
||||||
@ -1438,59 +1304,54 @@ void beceem_parse_target_struct(PMINI_ADAPTER Adapter)
|
|||||||
Adapter->ulPowerSaveMode =
|
Adapter->ulPowerSaveMode =
|
||||||
(ntohl(Adapter->pstargetparams->HostDrvrConfig6)>>12)&0x0F;
|
(ntohl(Adapter->pstargetparams->HostDrvrConfig6)>>12)&0x0F;
|
||||||
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "DDR Setting: %x\n", Adapter->DDRSetting);
|
pr_info(DRV_NAME ": DDR Setting: %x\n", Adapter->DDRSetting);
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT,DBG_LVL_ALL, "Power Save Mode: %lx\n",
|
pr_info(DRV_NAME ": Power Save Mode: %lx\n", Adapter->ulPowerSaveMode);
|
||||||
Adapter->ulPowerSaveMode);
|
|
||||||
if(ntohl(Adapter->pstargetparams->HostDrvrConfig6) & AUTO_FIRM_DOWNLOAD)
|
if(ntohl(Adapter->pstargetparams->HostDrvrConfig6) & AUTO_FIRM_DOWNLOAD)
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Enabling Auto Firmware Download\n");
|
pr_info(DRV_NAME ": Enabling Auto Firmware Download\n");
|
||||||
Adapter->AutoFirmDld = TRUE;
|
Adapter->AutoFirmDld = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Disabling Auto Firmware Download\n");
|
pr_info(DRV_NAME ": Disabling Auto Firmware Download\n");
|
||||||
Adapter->AutoFirmDld = FALSE;
|
Adapter->AutoFirmDld = FALSE;
|
||||||
}
|
}
|
||||||
uiHostDrvrCfg6 = ntohl(Adapter->pstargetparams->HostDrvrConfig6);
|
uiHostDrvrCfg6 = ntohl(Adapter->pstargetparams->HostDrvrConfig6);
|
||||||
Adapter->bMipsConfig = (uiHostDrvrCfg6>>20)&0x01;
|
Adapter->bMipsConfig = (uiHostDrvrCfg6>>20)&0x01;
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"MIPSConfig : 0x%X\n",Adapter->bMipsConfig);
|
pr_info(DRV_NAME ": MIPSConfig : 0x%X\n",Adapter->bMipsConfig);
|
||||||
//used for backward compatibility.
|
//used for backward compatibility.
|
||||||
Adapter->bDPLLConfig = (uiHostDrvrCfg6>>19)&0x01;
|
Adapter->bDPLLConfig = (uiHostDrvrCfg6>>19)&0x01;
|
||||||
|
|
||||||
Adapter->PmuMode= (uiHostDrvrCfg6 >> 24 ) & 0x03;
|
Adapter->PmuMode= (uiHostDrvrCfg6 >> 24 ) & 0x03;
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "PMU MODE: %x", Adapter->PmuMode);
|
pr_info(DRV_NAME ": PMU MODE: %x", Adapter->PmuMode);
|
||||||
|
|
||||||
if((uiHostDrvrCfg6 >> HOST_BUS_SUSPEND_BIT ) & (0x01))
|
if((uiHostDrvrCfg6 >> HOST_BUS_SUSPEND_BIT ) & (0x01))
|
||||||
{
|
{
|
||||||
Adapter->bDoSuspend = TRUE;
|
Adapter->bDoSuspend = TRUE;
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Making DoSuspend TRUE as per configFile");
|
pr_info(DRV_NAME ": Making DoSuspend TRUE as per configFile");
|
||||||
}
|
}
|
||||||
|
|
||||||
uiEEPROMFlag = ntohl(Adapter->pstargetparams->m_u32EEPROMFlag);
|
uiEEPROMFlag = ntohl(Adapter->pstargetparams->m_u32EEPROMFlag);
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "uiEEPROMFlag : 0x%X\n",uiEEPROMFlag);
|
pr_info(DRV_NAME ": uiEEPROMFlag : 0x%X\n",uiEEPROMFlag);
|
||||||
Adapter->eNVMType = (NVM_TYPE)((uiEEPROMFlag>>4)&0x3);
|
Adapter->eNVMType = (NVM_TYPE)((uiEEPROMFlag>>4)&0x3);
|
||||||
|
|
||||||
|
|
||||||
Adapter->bStatusWrite = (uiEEPROMFlag>>6)&0x1;
|
Adapter->bStatusWrite = (uiEEPROMFlag>>6)&0x1;
|
||||||
//printk(("bStatusWrite : 0x%X\n", Adapter->bStatusWrite));
|
|
||||||
|
|
||||||
Adapter->uiSectorSizeInCFG = 1024*(0xFFFF & ntohl(Adapter->pstargetparams->HostDrvrConfig4));
|
Adapter->uiSectorSizeInCFG = 1024*(0xFFFF & ntohl(Adapter->pstargetparams->HostDrvrConfig4));
|
||||||
//printk(("uiSectorSize : 0x%X\n", Adapter->uiSectorSizeInCFG));
|
|
||||||
|
|
||||||
Adapter->bSectorSizeOverride =(bool) ((ntohl(Adapter->pstargetparams->HostDrvrConfig4))>>16)&0x1;
|
Adapter->bSectorSizeOverride =(bool) ((ntohl(Adapter->pstargetparams->HostDrvrConfig4))>>16)&0x1;
|
||||||
//printk(MP_INIT,("bSectorSizeOverride : 0x%X\n",Adapter->bSectorSizeOverride));
|
|
||||||
|
|
||||||
if(ntohl(Adapter->pstargetparams->m_u32PowerSavingModeOptions) &0x01)
|
if(ntohl(Adapter->pstargetparams->m_u32PowerSavingModeOptions) &0x01)
|
||||||
Adapter->ulPowerSaveMode = DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE;
|
Adapter->ulPowerSaveMode = DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE;
|
||||||
//autocorrection part
|
|
||||||
if(Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE)
|
if(Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE)
|
||||||
doPowerAutoCorrection(Adapter);
|
doPowerAutoCorrection(Adapter);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID doPowerAutoCorrection(PMINI_ADAPTER psAdapter)
|
static VOID doPowerAutoCorrection(PMINI_ADAPTER psAdapter)
|
||||||
{
|
{
|
||||||
UINT reporting_mode = 0;
|
UINT reporting_mode;
|
||||||
|
|
||||||
reporting_mode = ntohl(psAdapter->pstargetparams->m_u32PowerSavingModeOptions) &0x02 ;
|
reporting_mode = ntohl(psAdapter->pstargetparams->m_u32PowerSavingModeOptions) &0x02 ;
|
||||||
psAdapter->bIsAutoCorrectEnabled = !((char)(psAdapter->ulPowerSaveMode >> 3) & 0x1);
|
psAdapter->bIsAutoCorrectEnabled = !((char)(psAdapter->ulPowerSaveMode >> 3) & 0x1);
|
||||||
@ -1504,20 +1365,9 @@ VOID doPowerAutoCorrection(PMINI_ADAPTER psAdapter)
|
|||||||
if (psAdapter->bIsAutoCorrectEnabled && (psAdapter->chip_id >= T3LPB))
|
if (psAdapter->bIsAutoCorrectEnabled && (psAdapter->chip_id >= T3LPB))
|
||||||
{
|
{
|
||||||
//If reporting mode is enable, switch PMU to PMC
|
//If reporting mode is enable, switch PMU to PMC
|
||||||
#if 0
|
|
||||||
if(reporting_mode == FALSE)
|
|
||||||
{
|
|
||||||
psAdapter->ulPowerSaveMode = DEVICE_POWERSAVE_MODE_AS_PMU_SHUTDOWN;
|
|
||||||
psAdapter->bDoSuspend = TRUE;
|
|
||||||
BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"PMU selected ....");
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
psAdapter->ulPowerSaveMode = DEVICE_POWERSAVE_MODE_AS_PMU_CLOCK_GATING;
|
psAdapter->ulPowerSaveMode = DEVICE_POWERSAVE_MODE_AS_PMU_CLOCK_GATING;
|
||||||
psAdapter->bDoSuspend =FALSE;
|
psAdapter->bDoSuspend =FALSE;
|
||||||
BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"PMC selected..");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1540,12 +1390,10 @@ VOID doPowerAutoCorrection(PMINI_ADAPTER psAdapter)
|
|||||||
#if 0
|
#if 0
|
||||||
static unsigned char *ReadMacAddrEEPROM(PMINI_ADAPTER Adapter, ulong dwAddress)
|
static unsigned char *ReadMacAddrEEPROM(PMINI_ADAPTER Adapter, ulong dwAddress)
|
||||||
{
|
{
|
||||||
unsigned char *pucmacaddr = NULL;
|
int status = 0, i = 0;
|
||||||
int status = 0, i=0;
|
unsigned int temp = 0;
|
||||||
unsigned int temp =0;
|
unsigned char *pucmacaddr = kmalloc(MAC_ADDRESS_SIZE, GFP_KERNEL);
|
||||||
|
|
||||||
|
|
||||||
pucmacaddr = (unsigned char *)kmalloc(MAC_ADDRESS_SIZE, GFP_KERNEL);
|
|
||||||
if(!pucmacaddr)
|
if(!pucmacaddr)
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "No Buffers to Read the EEPROM Address\n");
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "No Buffers to Read the EEPROM Address\n");
|
||||||
@ -1558,7 +1406,7 @@ static unsigned char *ReadMacAddrEEPROM(PMINI_ADAPTER Adapter, ulong dwAddress)
|
|||||||
if(status != STATUS_SUCCESS)
|
if(status != STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "wrm Failed..\n");
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "wrm Failed..\n");
|
||||||
bcm_kfree(pucmacaddr);
|
kfree(pucmacaddr);
|
||||||
pucmacaddr = NULL;
|
pucmacaddr = NULL;
|
||||||
goto OUT;
|
goto OUT;
|
||||||
}
|
}
|
||||||
@ -1568,7 +1416,7 @@ static unsigned char *ReadMacAddrEEPROM(PMINI_ADAPTER Adapter, ulong dwAddress)
|
|||||||
if(status != STATUS_SUCCESS)
|
if(status != STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "rdm Failed..\n");
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "rdm Failed..\n");
|
||||||
bcm_kfree(pucmacaddr);
|
kfree(pucmacaddr);
|
||||||
pucmacaddr = NULL;
|
pucmacaddr = NULL;
|
||||||
goto OUT;
|
goto OUT;
|
||||||
}
|
}
|
||||||
@ -1580,43 +1428,6 @@ static unsigned char *ReadMacAddrEEPROM(PMINI_ADAPTER Adapter, ulong dwAddress)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0
|
|
||||||
INT ReadMacAddressFromEEPROM(PMINI_ADAPTER Adapter)
|
|
||||||
{
|
|
||||||
unsigned char *puMacAddr = NULL;
|
|
||||||
int i =0;
|
|
||||||
|
|
||||||
puMacAddr = ReadMacAddrEEPROM(Adapter,0x200);
|
|
||||||
if(!puMacAddr)
|
|
||||||
{
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Couldn't retrieve the Mac Address\n");
|
|
||||||
return STATUS_FAILURE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if((puMacAddr[0] == 0x0 && puMacAddr[1] == 0x0 &&
|
|
||||||
puMacAddr[2] == 0x0 && puMacAddr[3] == 0x0 &&
|
|
||||||
puMacAddr[4] == 0x0 && puMacAddr[5] == 0x0) ||
|
|
||||||
(puMacAddr[0] == 0xFF && puMacAddr[1] == 0xFF &&
|
|
||||||
puMacAddr[2] == 0xFF && puMacAddr[3] == 0xFF &&
|
|
||||||
puMacAddr[4] == 0xFF && puMacAddr[5] == 0xFF))
|
|
||||||
{
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Invalid Mac Address\n");
|
|
||||||
bcm_kfree(puMacAddr);
|
|
||||||
return STATUS_FAILURE;
|
|
||||||
}
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "The Mac Address received is: \n");
|
|
||||||
memcpy(Adapter->dev->dev_addr, puMacAddr, MAC_ADDRESS_SIZE);
|
|
||||||
for(i=0;i<MAC_ADDRESS_SIZE;i++)
|
|
||||||
{
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"%02x ", Adapter->dev->dev_addr[i]);
|
|
||||||
}
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"\n");
|
|
||||||
bcm_kfree(puMacAddr);
|
|
||||||
}
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void convertEndian(B_UINT8 rwFlag, PUINT puiBuffer, UINT uiByteCount)
|
static void convertEndian(B_UINT8 rwFlag, PUINT puiBuffer, UINT uiByteCount)
|
||||||
{
|
{
|
||||||
@ -1640,81 +1451,21 @@ int rdm(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize)
|
|||||||
{
|
{
|
||||||
INT uiRetVal =0;
|
INT uiRetVal =0;
|
||||||
|
|
||||||
#ifndef BCM_SHM_INTERFACE
|
|
||||||
uiRetVal = Adapter->interface_rdm(Adapter->pvInterfaceAdapter,
|
uiRetVal = Adapter->interface_rdm(Adapter->pvInterfaceAdapter,
|
||||||
uiAddress, pucBuff, sSize);
|
uiAddress, pucBuff, sSize);
|
||||||
|
|
||||||
if(uiRetVal < 0)
|
if(uiRetVal < 0)
|
||||||
return uiRetVal;
|
return uiRetVal;
|
||||||
|
|
||||||
#else
|
|
||||||
int indx;
|
|
||||||
uiRetVal = STATUS_SUCCESS;
|
|
||||||
if(uiAddress & 0x10000000) {
|
|
||||||
// DDR Memory Access
|
|
||||||
uiAddress |= CACHE_ADDRESS_MASK;
|
|
||||||
memcpy(pucBuff,(unsigned char *)uiAddress ,sSize);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Register, SPRAM, Flash
|
|
||||||
uiAddress |= UNCACHE_ADDRESS_MASK;
|
|
||||||
if ((uiAddress & FLASH_ADDR_MASK) == (FLASH_CONTIGIOUS_START_ADDR_BCS350 & FLASH_ADDR_MASK))
|
|
||||||
{
|
|
||||||
#if defined(FLASH_DIRECT_ACCESS)
|
|
||||||
memcpy(pucBuff,(unsigned char *)uiAddress ,sSize);
|
|
||||||
#else
|
|
||||||
printk("\nInvalid GSPI ACCESS :Addr :%#X", uiAddress);
|
|
||||||
uiRetVal = STATUS_FAILURE;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else if(((unsigned int )uiAddress & 0x3) ||
|
|
||||||
((unsigned int )pucBuff & 0x3) ||
|
|
||||||
((unsigned int )sSize & 0x3)) {
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"rdmalt :unalligned register access uiAddress = %x,pucBuff = %x size = %x\n",(unsigned int )uiAddress,(unsigned int )pucBuff,(unsigned int )sSize);
|
|
||||||
uiRetVal = STATUS_FAILURE;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for (indx=0;indx<sSize;indx+=4){
|
|
||||||
*(PUINT)(pucBuff + indx) = *(PUINT)(uiAddress + indx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return uiRetVal;
|
return uiRetVal;
|
||||||
}
|
}
|
||||||
int wrm(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize)
|
int wrm(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize)
|
||||||
{
|
{
|
||||||
int iRetVal;
|
int iRetVal;
|
||||||
|
|
||||||
#ifndef BCM_SHM_INTERFACE
|
|
||||||
iRetVal = Adapter->interface_wrm(Adapter->pvInterfaceAdapter,
|
iRetVal = Adapter->interface_wrm(Adapter->pvInterfaceAdapter,
|
||||||
uiAddress, pucBuff, sSize);
|
uiAddress, pucBuff, sSize);
|
||||||
|
|
||||||
#else
|
|
||||||
int indx;
|
|
||||||
if(uiAddress & 0x10000000) {
|
|
||||||
// DDR Memory Access
|
|
||||||
uiAddress |= CACHE_ADDRESS_MASK;
|
|
||||||
memcpy((unsigned char *)(uiAddress),pucBuff,sSize);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Register, SPRAM, Flash
|
|
||||||
uiAddress |= UNCACHE_ADDRESS_MASK;
|
|
||||||
|
|
||||||
if(((unsigned int )uiAddress & 0x3) ||
|
|
||||||
((unsigned int )pucBuff & 0x3) ||
|
|
||||||
((unsigned int )sSize & 0x3)) {
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"wrmalt: unalligned register access uiAddress = %x,pucBuff = %x size = %x\n",(unsigned int )uiAddress,(unsigned int )pucBuff,(unsigned int )sSize);
|
|
||||||
iRetVal = STATUS_FAILURE;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for (indx=0;indx<sSize;indx+=4) {
|
|
||||||
*(PUINT)(uiAddress + indx) = *(PUINT)(pucBuff + indx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
iRetVal = STATUS_SUCCESS;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return iRetVal;
|
return iRetVal;
|
||||||
}
|
}
|
||||||
@ -1735,26 +1486,7 @@ int rdmalt (PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t size)
|
|||||||
return uiRetVal;
|
return uiRetVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rdmWithLock(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize)
|
|
||||||
{
|
|
||||||
|
|
||||||
INT status = STATUS_SUCCESS ;
|
|
||||||
down(&Adapter->rdmwrmsync);
|
|
||||||
|
|
||||||
if((Adapter->IdleMode == TRUE) ||
|
|
||||||
(Adapter->bShutStatus ==TRUE) ||
|
|
||||||
(Adapter->bPreparingForLowPowerMode ==TRUE))
|
|
||||||
{
|
|
||||||
status = -EACCES;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = rdm(Adapter, uiAddress, pucBuff, sSize);
|
|
||||||
|
|
||||||
exit:
|
|
||||||
up(&Adapter->rdmwrmsync);
|
|
||||||
return status ;
|
|
||||||
}
|
|
||||||
int wrmWithLock(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize)
|
int wrmWithLock(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize)
|
||||||
{
|
{
|
||||||
INT status = STATUS_SUCCESS ;
|
INT status = STATUS_SUCCESS ;
|
||||||
@ -1921,10 +1653,8 @@ static VOID SendShutModeResponse(PMINI_ADAPTER Adapter)
|
|||||||
Adapter->bPreparingForLowPowerMode = TRUE;
|
Adapter->bPreparingForLowPowerMode = TRUE;
|
||||||
up(&Adapter->rdmwrmsync);
|
up(&Adapter->rdmwrmsync);
|
||||||
//Killing all URBS.
|
//Killing all URBS.
|
||||||
#ifndef BCM_SHM_INTERFACE
|
|
||||||
if(Adapter->bDoSuspend == TRUE)
|
if(Adapter->bDoSuspend == TRUE)
|
||||||
Bcm_kill_all_URBs((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));
|
Bcm_kill_all_URBs((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1943,14 +1673,12 @@ static VOID SendShutModeResponse(PMINI_ADAPTER Adapter)
|
|||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL,"fail to send the Idle mode Request \n");
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL,"fail to send the Idle mode Request \n");
|
||||||
Adapter->bPreparingForLowPowerMode = FALSE;
|
Adapter->bPreparingForLowPowerMode = FALSE;
|
||||||
|
|
||||||
#ifndef BCM_SHM_INTERFACE
|
|
||||||
StartInterruptUrb((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));
|
StartInterruptUrb((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void HandleShutDownModeRequest(PMINI_ADAPTER Adapter,PUCHAR pucBuffer)
|
static void HandleShutDownModeRequest(PMINI_ADAPTER Adapter,PUCHAR pucBuffer)
|
||||||
{
|
{
|
||||||
B_UINT32 uiResetValue = 0;
|
B_UINT32 uiResetValue = 0;
|
||||||
|
|
||||||
@ -2077,11 +1805,7 @@ void update_per_sf_desc_cnts( PMINI_ADAPTER Adapter)
|
|||||||
if(!atomic_read (&Adapter->uiMBupdate))
|
if(!atomic_read (&Adapter->uiMBupdate))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#ifdef BCM_SHM_INTERFACE
|
|
||||||
if(rdmalt(Adapter, TARGET_SFID_TXDESC_MAP_LOC, (PUINT)uibuff, sizeof(UINT) * MAX_TARGET_DSX_BUFFERS)<0)
|
|
||||||
#else
|
|
||||||
if(rdmaltWithLock(Adapter, TARGET_SFID_TXDESC_MAP_LOC, (PUINT)uibuff, sizeof(UINT) * MAX_TARGET_DSX_BUFFERS)<0)
|
if(rdmaltWithLock(Adapter, TARGET_SFID_TXDESC_MAP_LOC, (PUINT)uibuff, sizeof(UINT) * MAX_TARGET_DSX_BUFFERS)<0)
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "rdm failed\n");
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "rdm failed\n");
|
||||||
return;
|
return;
|
||||||
@ -2107,9 +1831,7 @@ void update_per_sf_desc_cnts( PMINI_ADAPTER Adapter)
|
|||||||
void flush_queue(PMINI_ADAPTER Adapter, UINT iQIndex)
|
void flush_queue(PMINI_ADAPTER Adapter, UINT iQIndex)
|
||||||
{
|
{
|
||||||
struct sk_buff* PacketToDrop=NULL;
|
struct sk_buff* PacketToDrop=NULL;
|
||||||
struct net_device_stats* netstats=NULL;
|
struct net_device_stats* netstats = &Adapter->dev->stats;
|
||||||
|
|
||||||
netstats = &((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats;
|
|
||||||
|
|
||||||
spin_lock_bh(&Adapter->PackInfo[iQIndex].SFQueueLock);
|
spin_lock_bh(&Adapter->PackInfo[iQIndex].SFQueueLock);
|
||||||
|
|
||||||
@ -2130,25 +1852,23 @@ void flush_queue(PMINI_ADAPTER Adapter, UINT iQIndex)
|
|||||||
Adapter->PackInfo[iQIndex].uiDroppedCountBytes += PacketToDrop->len;
|
Adapter->PackInfo[iQIndex].uiDroppedCountBytes += PacketToDrop->len;
|
||||||
Adapter->PackInfo[iQIndex].uiDroppedCountPackets++;
|
Adapter->PackInfo[iQIndex].uiDroppedCountPackets++;
|
||||||
|
|
||||||
bcm_kfree_skb(PacketToDrop);
|
dev_kfree_skb(PacketToDrop);
|
||||||
atomic_dec(&Adapter->TotalPacketCount);
|
atomic_dec(&Adapter->TotalPacketCount);
|
||||||
atomic_inc(&Adapter->TxDroppedPacketCount);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spin_unlock_bh(&Adapter->PackInfo[iQIndex].SFQueueLock);
|
spin_unlock_bh(&Adapter->PackInfo[iQIndex].SFQueueLock);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void beceem_protocol_reset (PMINI_ADAPTER Adapter)
|
static void beceem_protocol_reset (PMINI_ADAPTER Adapter)
|
||||||
{
|
{
|
||||||
int i =0;
|
int i;
|
||||||
|
|
||||||
if(NULL != Adapter->dev)
|
if (netif_msg_link(Adapter))
|
||||||
{
|
pr_notice(PFX "%s: protocol reset\n", Adapter->dev->name);
|
||||||
netif_carrier_off(Adapter->dev);
|
|
||||||
netif_stop_queue(Adapter->dev);
|
netif_carrier_off(Adapter->dev);
|
||||||
}
|
netif_stop_queue(Adapter->dev);
|
||||||
|
|
||||||
Adapter->IdleMode = FALSE;
|
Adapter->IdleMode = FALSE;
|
||||||
Adapter->LinkUpStatus = FALSE;
|
Adapter->LinkUpStatus = FALSE;
|
||||||
@ -2166,78 +1886,18 @@ void beceem_protocol_reset (PMINI_ADAPTER Adapter)
|
|||||||
Adapter->TimerActive = FALSE;
|
Adapter->TimerActive = FALSE;
|
||||||
|
|
||||||
memset(Adapter->astFragmentedPktClassifierTable, 0,
|
memset(Adapter->astFragmentedPktClassifierTable, 0,
|
||||||
sizeof(S_FRAGMENTED_PACKET_INFO) *
|
sizeof(S_FRAGMENTED_PACKET_INFO) * MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES);
|
||||||
MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES);
|
|
||||||
|
|
||||||
for(i = 0;i<HiPriority;i++)
|
for(i = 0;i<HiPriority;i++)
|
||||||
{
|
{
|
||||||
//resetting only the first size (S_MIBS_SERVICEFLOW_TABLE) for the SF.
|
//resetting only the first size (S_MIBS_SERVICEFLOW_TABLE) for the SF.
|
||||||
// It is same between MIBs and SF.
|
// It is same between MIBs and SF.
|
||||||
memset((PVOID)&Adapter->PackInfo[i],0,sizeof(S_MIBS_SERVICEFLOW_TABLE));
|
memset(&Adapter->PackInfo[i].stMibsExtServiceFlowTable,
|
||||||
|
0, sizeof(S_MIBS_EXTSERVICEFLOW_PARAMETERS));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef BCM_SHM_INTERFACE
|
|
||||||
|
|
||||||
|
|
||||||
#define GET_GTB_DIFF(start, end) \
|
|
||||||
( (start) < (end) )? ( (end) - (start) ) : ( ~0x0 - ( (start) - (end)) +1 )
|
|
||||||
|
|
||||||
void usdelay ( unsigned int a) {
|
|
||||||
unsigned int start= *(unsigned int *)0xaf8051b4;
|
|
||||||
unsigned int end = start+1;
|
|
||||||
unsigned int diff = 0;
|
|
||||||
|
|
||||||
while(1) {
|
|
||||||
end = *(unsigned int *)0xaf8051b4;
|
|
||||||
diff = (GET_GTB_DIFF(start,end))/80;
|
|
||||||
if (diff >= a)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void read_cfg_file(PMINI_ADAPTER Adapter) {
|
|
||||||
|
|
||||||
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Config File Version = 0x%x \n",Adapter->pstargetparams->m_u32CfgVersion );
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Center Frequency = 0x%x \n",Adapter->pstargetparams->m_u32CenterFrequency );
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Band A Scan = 0x%x \n",Adapter->pstargetparams->m_u32BandAScan );
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Band B Scan = 0x%x \n",Adapter->pstargetparams->m_u32BandBScan );
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Band C Scan = 0x%x \n",Adapter->pstargetparams->m_u32BandCScan );
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"ERTPS Options = 0x%x \n",Adapter->pstargetparams->m_u32ErtpsOptions );
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"PHS Enable = 0x%x \n",Adapter->pstargetparams->m_u32PHSEnable );
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Handoff Enable = 0x%x \n",Adapter->pstargetparams->m_u32HoEnable );
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HO Reserved1 = 0x%x \n",Adapter->pstargetparams->m_u32HoReserved1 );
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HO Reserved2 = 0x%x \n",Adapter->pstargetparams->m_u32HoReserved2 );
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"MIMO Enable = 0x%x \n",Adapter->pstargetparams->m_u32MimoEnable );
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"PKMv2 Enable = 0x%x \n",Adapter->pstargetparams->m_u32SecurityEnable );
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Powersaving Modes Enable = 0x%x \n",Adapter->pstargetparams->m_u32PowerSavingModesEnable );
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Power Saving Mode Options = 0x%x \n",Adapter->pstargetparams->m_u32PowerSavingModeOptions );
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"ARQ Enable = 0x%x \n",Adapter->pstargetparams->m_u32ArqEnable );
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Harq Enable = 0x%x \n",Adapter->pstargetparams->m_u32HarqEnable );
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"EEPROM Flag = 0x%x \n",Adapter->pstargetparams->m_u32EEPROMFlag );
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Customize = 0x%x \n",Adapter->pstargetparams->m_u32Customize );
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Bandwidth = 0x%x \n",Adapter->pstargetparams->m_u32ConfigBW );
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"ShutDown Timer Value = 0x%x \n",Adapter->pstargetparams->m_u32ShutDownInitThresholdTimer );
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"RadioParameter = 0x%x \n",Adapter->pstargetparams->m_u32RadioParameter );
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"PhyParameter1 = 0x%x \n",Adapter->pstargetparams->m_u32PhyParameter1 );
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"PhyParameter2 = 0x%x \n",Adapter->pstargetparams->m_u32PhyParameter2 );
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"PhyParameter3 = 0x%x \n",Adapter->pstargetparams->m_u32PhyParameter3 );
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"m_u32TestOptions = 0x%x \n",Adapter->pstargetparams->m_u32TestOptions );
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"MaxMACDataperDLFrame = 0x%x \n",Adapter->pstargetparams->m_u32MaxMACDataperDLFrame );
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"MaxMACDataperULFrame = 0x%x \n",Adapter->pstargetparams->m_u32MaxMACDataperULFrame );
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Corr2MacFlags = 0x%x \n",Adapter->pstargetparams->m_u32Corr2MacFlags );
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HostDrvrConfig1 = 0x%x \n",Adapter->pstargetparams->HostDrvrConfig1 );
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HostDrvrConfig2 = 0x%x \n",Adapter->pstargetparams->HostDrvrConfig2 );
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HostDrvrConfig3 = 0x%x \n",Adapter->pstargetparams->HostDrvrConfig3 );
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HostDrvrConfig4 = 0x%x \n",Adapter->pstargetparams->HostDrvrConfig4 );
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HostDrvrConfig5 = 0x%x \n",Adapter->pstargetparams->HostDrvrConfig5 );
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HostDrvrConfig6 = 0x%x \n",Adapter->pstargetparams->HostDrvrConfig6 );
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Segmented PUSC Enable = 0x%x \n",Adapter->pstargetparams->m_u32SegmentedPUSCenable );
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"BamcEnable = 0x%x \n",Adapter->pstargetparams->m_u32BandAMCEnable );
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
/*++
|
|
||||||
|
|
||||||
Copyright (c) Beceem Communications Inc.
|
|
||||||
|
|
||||||
Module Name:
|
|
||||||
WIN_Misc.c
|
|
||||||
|
|
||||||
Abstract:
|
|
||||||
Implements the Miscelanneous OS Construts
|
|
||||||
Linked Lists
|
|
||||||
Dispatcher Objects(Events,Semaphores,Spin Locks and the like)
|
|
||||||
Files
|
|
||||||
|
|
||||||
Revision History:
|
|
||||||
Who When What
|
|
||||||
-------- -------- ----------------------------------------------
|
|
||||||
Name Date Created/reviewed/modified
|
|
||||||
Rajeev 24/1/08 Created
|
|
||||||
Notes:
|
|
||||||
|
|
||||||
--*/
|
|
||||||
#include "headers.h"
|
|
||||||
|
|
||||||
bool OsalMemCompare(void *dest, void *src, UINT len)
|
|
||||||
{
|
|
||||||
return (memcmp(src, dest, len));
|
|
||||||
}
|
|
@ -1,10 +1,54 @@
|
|||||||
#include "headers.h"
|
#include "headers.h"
|
||||||
|
|
||||||
|
static UINT CreateSFToClassifierRuleMapping(B_UINT16 uiVcid,B_UINT16 uiClsId,S_SERVICEFLOW_TABLE *psServiceFlowTable,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI);
|
||||||
|
|
||||||
|
static UINT CreateClassiferToPHSRuleMapping(B_UINT16 uiVcid,B_UINT16 uiClsId,S_SERVICEFLOW_ENTRY *pstServiceFlowEntry,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI);
|
||||||
|
|
||||||
|
static UINT CreateClassifierPHSRule(B_UINT16 uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,B_UINT8 u8AssociatedPHSI);
|
||||||
|
|
||||||
|
static UINT UpdateClassifierPHSRule(B_UINT16 uiClsId,S_CLASSIFIER_ENTRY *pstClassifierEntry,S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI);
|
||||||
|
|
||||||
|
static BOOLEAN ValidatePHSRuleComplete(S_PHS_RULE *psPhsRule);
|
||||||
|
|
||||||
|
static BOOLEAN DerefPhsRule(B_UINT16 uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable,S_PHS_RULE *pstPhsRule);
|
||||||
|
|
||||||
|
static UINT GetClassifierEntry(S_CLASSIFIER_TABLE *pstClassifierTable,B_UINT32 uiClsid,E_CLASSIFIER_ENTRY_CONTEXT eClsContext, S_CLASSIFIER_ENTRY **ppstClassifierEntry);
|
||||||
|
|
||||||
|
static UINT GetPhsRuleEntry(S_CLASSIFIER_TABLE *pstClassifierTable,B_UINT32 uiPHSI,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,S_PHS_RULE **ppstPhsRule);
|
||||||
|
|
||||||
|
static void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable);
|
||||||
|
|
||||||
|
static int phs_compress(S_PHS_RULE *phs_members,unsigned char *in_buf,
|
||||||
|
unsigned char *out_buf,unsigned int *header_size,UINT *new_header_size );
|
||||||
|
|
||||||
|
|
||||||
|
static int verify_suppress_phsf(unsigned char *in_buffer,unsigned char *out_buffer,
|
||||||
|
unsigned char *phsf,unsigned char *phsm,unsigned int phss,unsigned int phsv,UINT *new_header_size );
|
||||||
|
|
||||||
|
static int phs_decompress(unsigned char *in_buf,unsigned char *out_buf,\
|
||||||
|
S_PHS_RULE *phs_rules,UINT *header_size);
|
||||||
|
|
||||||
|
|
||||||
|
static ULONG PhsCompress(void* pvContext,
|
||||||
|
B_UINT16 uiVcid,
|
||||||
|
B_UINT16 uiClsId,
|
||||||
|
void *pvInputBuffer,
|
||||||
|
void *pvOutputBuffer,
|
||||||
|
UINT *pOldHeaderSize,
|
||||||
|
UINT *pNewHeaderSize );
|
||||||
|
|
||||||
|
static ULONG PhsDeCompress(void* pvContext,
|
||||||
|
B_UINT16 uiVcid,
|
||||||
|
void *pvInputBuffer,
|
||||||
|
void *pvOutputBuffer,
|
||||||
|
UINT *pInHeaderSize,
|
||||||
|
UINT *pOutHeaderSize);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define IN
|
#define IN
|
||||||
#define OUT
|
#define OUT
|
||||||
|
|
||||||
void DumpDataPacketHeader(PUCHAR pPkt);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Function: PHSTransmit
|
Function: PHSTransmit
|
||||||
|
|
||||||
@ -81,8 +125,6 @@ int PHSTransmit(PMINI_ADAPTER Adapter,
|
|||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
//DumpDataPacketHeader(pucPHSPktHdrInBuf);
|
|
||||||
|
|
||||||
// Step 2 Supress Header using PHS and fill into intermediate ucaPHSPktHdrOutBuf.
|
// Step 2 Supress Header using PHS and fill into intermediate ucaPHSPktHdrOutBuf.
|
||||||
// Suppress only if IP Header and PHS Enabled For the Service Flow
|
// Suppress only if IP Header and PHS Enabled For the Service Flow
|
||||||
if(((usPacketType == ETHERNET_FRAMETYPE_IPV4) ||
|
if(((usPacketType == ETHERNET_FRAMETYPE_IPV4) ||
|
||||||
@ -120,15 +162,15 @@ int PHSTransmit(PMINI_ADAPTER Adapter,
|
|||||||
if(newPacket == NULL)
|
if(newPacket == NULL)
|
||||||
return STATUS_FAILURE;
|
return STATUS_FAILURE;
|
||||||
|
|
||||||
bcm_kfree_skb(Packet);
|
dev_kfree_skb(Packet);
|
||||||
*pPacket = Packet = newPacket;
|
*pPacket = Packet = newPacket;
|
||||||
pucPHSPktHdrInBuf = Packet->data + BytesToRemove;
|
pucPHSPktHdrInBuf = Packet->data + BytesToRemove;
|
||||||
}
|
}
|
||||||
|
|
||||||
numBytesCompressed = unPhsOldHdrSize - (unPHSNewPktHeaderLen+PHSI_LEN);
|
numBytesCompressed = unPhsOldHdrSize - (unPHSNewPktHeaderLen+PHSI_LEN);
|
||||||
|
|
||||||
OsalMemMove(pucPHSPktHdrInBuf + numBytesCompressed, pucPHSPktHdrOutBuf, unPHSNewPktHeaderLen + PHSI_LEN);
|
memcpy(pucPHSPktHdrInBuf + numBytesCompressed, pucPHSPktHdrOutBuf, unPHSNewPktHeaderLen + PHSI_LEN);
|
||||||
OsalMemMove(Packet->data + numBytesCompressed, Packet->data, BytesToRemove);
|
memcpy(Packet->data + numBytesCompressed, Packet->data, BytesToRemove);
|
||||||
skb_pull(Packet, numBytesCompressed);
|
skb_pull(Packet, numBytesCompressed);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
@ -223,23 +265,12 @@ int PHSRecieve(PMINI_ADAPTER Adapter,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OsalMemMove(packet->data, Adapter->ucaPHSPktRestoreBuf, nStandardPktHdrLen);
|
memcpy(packet->data, Adapter->ucaPHSPktRestoreBuf, nStandardPktHdrLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DumpDataPacketHeader(PUCHAR pPkt)
|
|
||||||
{
|
|
||||||
struct iphdr *iphd = (struct iphdr*)pPkt;
|
|
||||||
PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"Phs Send/Recieve : IP Packet Hdr \n");
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"TOS : %x \n",iphd->tos);
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"Src IP : %x \n",iphd->saddr);
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"Dest IP : %x \n \n",iphd->daddr);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void DumpFullPacket(UCHAR *pBuf,UINT nPktLen)
|
void DumpFullPacket(UCHAR *pBuf,UINT nPktLen)
|
||||||
{
|
{
|
||||||
PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
|
PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
|
||||||
@ -270,15 +301,9 @@ int phs_init(PPHS_DEVICE_EXTENSION pPhsdeviceExtension,PMINI_ADAPTER Adapter)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
pPhsdeviceExtension->pstServiceFlowPhsRulesTable =
|
pPhsdeviceExtension->pstServiceFlowPhsRulesTable =
|
||||||
(S_SERVICEFLOW_TABLE*)OsalMemAlloc(sizeof(S_SERVICEFLOW_TABLE),
|
kzalloc(sizeof(S_SERVICEFLOW_TABLE), GFP_KERNEL);
|
||||||
PHS_MEM_TAG);
|
|
||||||
|
|
||||||
if(pPhsdeviceExtension->pstServiceFlowPhsRulesTable)
|
if(!pPhsdeviceExtension->pstServiceFlowPhsRulesTable)
|
||||||
{
|
|
||||||
OsalZeroMemory(pPhsdeviceExtension->pstServiceFlowPhsRulesTable,
|
|
||||||
sizeof(S_SERVICEFLOW_TABLE));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation ServiceFlowPhsRulesTable failed");
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation ServiceFlowPhsRulesTable failed");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@ -288,14 +313,8 @@ int phs_init(PPHS_DEVICE_EXTENSION pPhsdeviceExtension,PMINI_ADAPTER Adapter)
|
|||||||
for(i=0;i<MAX_SERVICEFLOWS;i++)
|
for(i=0;i<MAX_SERVICEFLOWS;i++)
|
||||||
{
|
{
|
||||||
S_SERVICEFLOW_ENTRY sServiceFlow = pstServiceFlowTable->stSFList[i];
|
S_SERVICEFLOW_ENTRY sServiceFlow = pstServiceFlowTable->stSFList[i];
|
||||||
sServiceFlow.pstClassifierTable = (S_CLASSIFIER_TABLE*)OsalMemAlloc(
|
sServiceFlow.pstClassifierTable = kzalloc(sizeof(S_CLASSIFIER_TABLE), GFP_KERNEL);
|
||||||
sizeof(S_CLASSIFIER_TABLE), PHS_MEM_TAG);
|
if(!sServiceFlow.pstClassifierTable)
|
||||||
if(sServiceFlow.pstClassifierTable)
|
|
||||||
{
|
|
||||||
OsalZeroMemory(sServiceFlow.pstClassifierTable,sizeof(S_CLASSIFIER_TABLE));
|
|
||||||
pstServiceFlowTable->stSFList[i].pstClassifierTable = sServiceFlow.pstClassifierTable;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed");
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed");
|
||||||
free_phs_serviceflow_rules(pPhsdeviceExtension->
|
free_phs_serviceflow_rules(pPhsdeviceExtension->
|
||||||
@ -305,9 +324,7 @@ int phs_init(PPHS_DEVICE_EXTENSION pPhsdeviceExtension,PMINI_ADAPTER Adapter)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pPhsdeviceExtension->CompressedTxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL);
|
||||||
pPhsdeviceExtension->CompressedTxBuffer =
|
|
||||||
OsalMemAlloc(PHS_BUFFER_SIZE,PHS_MEM_TAG);
|
|
||||||
|
|
||||||
if(pPhsdeviceExtension->CompressedTxBuffer == NULL)
|
if(pPhsdeviceExtension->CompressedTxBuffer == NULL)
|
||||||
{
|
{
|
||||||
@ -317,12 +334,11 @@ int phs_init(PPHS_DEVICE_EXTENSION pPhsdeviceExtension,PMINI_ADAPTER Adapter)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
pPhsdeviceExtension->UnCompressedRxBuffer =
|
pPhsdeviceExtension->UnCompressedRxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL);
|
||||||
OsalMemAlloc(PHS_BUFFER_SIZE,PHS_MEM_TAG);
|
|
||||||
if(pPhsdeviceExtension->UnCompressedRxBuffer == NULL)
|
if(pPhsdeviceExtension->UnCompressedRxBuffer == NULL)
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed");
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed");
|
||||||
OsalMemFree(pPhsdeviceExtension->CompressedTxBuffer,PHS_BUFFER_SIZE);
|
kfree(pPhsdeviceExtension->CompressedTxBuffer);
|
||||||
free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable);
|
free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable);
|
||||||
pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
|
pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@ -343,16 +359,11 @@ int PhsCleanup(IN PPHS_DEVICE_EXTENSION pPHSDeviceExt)
|
|||||||
pPHSDeviceExt->pstServiceFlowPhsRulesTable = NULL;
|
pPHSDeviceExt->pstServiceFlowPhsRulesTable = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pPHSDeviceExt->CompressedTxBuffer)
|
kfree(pPHSDeviceExt->CompressedTxBuffer);
|
||||||
{
|
pPHSDeviceExt->CompressedTxBuffer = NULL;
|
||||||
OsalMemFree(pPHSDeviceExt->CompressedTxBuffer,PHS_BUFFER_SIZE);
|
|
||||||
pPHSDeviceExt->CompressedTxBuffer = NULL;
|
kfree(pPHSDeviceExt->UnCompressedRxBuffer);
|
||||||
}
|
pPHSDeviceExt->UnCompressedRxBuffer = NULL;
|
||||||
if(pPHSDeviceExt->UnCompressedRxBuffer)
|
|
||||||
{
|
|
||||||
OsalMemFree(pPHSDeviceExt->UnCompressedRxBuffer,PHS_BUFFER_SIZE);
|
|
||||||
pPHSDeviceExt->UnCompressedRxBuffer = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -478,20 +489,12 @@ ULONG PhsDeletePHSRule(IN void* pvContext,IN B_UINT16 uiVcid,IN B_UINT8 u8PHSI)
|
|||||||
{
|
{
|
||||||
if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].bUsed && pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule)
|
if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].bUsed && pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule)
|
||||||
{
|
{
|
||||||
if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
|
if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8PHSI == u8PHSI) {
|
||||||
.pstPhsRule->u8PHSI == u8PHSI)
|
if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt)
|
||||||
{
|
pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt--;
|
||||||
if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule
|
if(0 == pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt)
|
||||||
->u8RefCnt)
|
kfree(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule);
|
||||||
pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule
|
memset(&pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex], 0,
|
||||||
->u8RefCnt--;
|
|
||||||
if(0 == pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
|
|
||||||
.pstPhsRule->u8RefCnt)
|
|
||||||
OsalMemFree(pstClassifierRulesTable
|
|
||||||
->stActivePhsRulesList[nClsidIndex].pstPhsRule,
|
|
||||||
sizeof(S_PHS_RULE));
|
|
||||||
OsalZeroMemory(&pstClassifierRulesTable
|
|
||||||
->stActivePhsRulesList[nClsidIndex],
|
|
||||||
sizeof(S_CLASSIFIER_ENTRY));
|
sizeof(S_CLASSIFIER_ENTRY));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -548,10 +551,10 @@ ULONG PhsDeleteClassifierRule(IN void* pvContext,IN B_UINT16 uiVcid ,IN B_UINT16
|
|||||||
if(pstClassifierEntry->pstPhsRule->u8RefCnt)
|
if(pstClassifierEntry->pstPhsRule->u8RefCnt)
|
||||||
pstClassifierEntry->pstPhsRule->u8RefCnt--;
|
pstClassifierEntry->pstPhsRule->u8RefCnt--;
|
||||||
if(0==pstClassifierEntry->pstPhsRule->u8RefCnt)
|
if(0==pstClassifierEntry->pstPhsRule->u8RefCnt)
|
||||||
OsalMemFree(pstClassifierEntry->pstPhsRule,sizeof(S_PHS_RULE));
|
kfree(pstClassifierEntry->pstPhsRule);
|
||||||
|
|
||||||
}
|
}
|
||||||
OsalZeroMemory(pstClassifierEntry,sizeof(S_CLASSIFIER_ENTRY));
|
memset(pstClassifierEntry, 0, sizeof(S_CLASSIFIER_ENTRY));
|
||||||
}
|
}
|
||||||
|
|
||||||
nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
|
nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
|
||||||
@ -559,10 +562,8 @@ ULONG PhsDeleteClassifierRule(IN void* pvContext,IN B_UINT16 uiVcid ,IN B_UINT16
|
|||||||
|
|
||||||
if((nClsidIndex != PHS_INVALID_TABLE_INDEX) && (!pstClassifierEntry->bUnclassifiedPHSRule))
|
if((nClsidIndex != PHS_INVALID_TABLE_INDEX) && (!pstClassifierEntry->bUnclassifiedPHSRule))
|
||||||
{
|
{
|
||||||
if(pstClassifierEntry->pstPhsRule)
|
kfree(pstClassifierEntry->pstPhsRule);
|
||||||
//Delete the classifier entry
|
memset(pstClassifierEntry, 0, sizeof(S_CLASSIFIER_ENTRY));
|
||||||
OsalMemFree(pstClassifierEntry->pstPhsRule,sizeof(S_PHS_RULE));
|
|
||||||
OsalZeroMemory(pstClassifierEntry,sizeof(S_CLASSIFIER_ENTRY));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return lStatus;
|
return lStatus;
|
||||||
@ -619,14 +620,11 @@ ULONG PhsDeleteSFRules(IN void* pvContext,IN B_UINT16 uiVcid)
|
|||||||
.pstPhsRule->u8RefCnt--;
|
.pstPhsRule->u8RefCnt--;
|
||||||
if(0==pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
|
if(0==pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
|
||||||
.pstPhsRule->u8RefCnt)
|
.pstPhsRule->u8RefCnt)
|
||||||
OsalMemFree(pstClassifierRulesTable
|
kfree(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule);
|
||||||
->stActivePhsRulesList[nClsidIndex].pstPhsRule,
|
|
||||||
sizeof(S_PHS_RULE));
|
|
||||||
pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
|
pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
|
||||||
.pstPhsRule = NULL;
|
.pstPhsRule = NULL;
|
||||||
}
|
}
|
||||||
OsalZeroMemory(&pstClassifierRulesTable
|
memset(&pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex], 0, sizeof(S_CLASSIFIER_ENTRY));
|
||||||
->stActivePhsRulesList[nClsidIndex],sizeof(S_CLASSIFIER_ENTRY));
|
|
||||||
if(pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule)
|
if(pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule)
|
||||||
{
|
{
|
||||||
if(pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
|
if(pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
|
||||||
@ -635,15 +633,12 @@ ULONG PhsDeleteSFRules(IN void* pvContext,IN B_UINT16 uiVcid)
|
|||||||
.pstPhsRule->u8RefCnt--;
|
.pstPhsRule->u8RefCnt--;
|
||||||
if(0 == pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
|
if(0 == pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
|
||||||
.pstPhsRule->u8RefCnt)
|
.pstPhsRule->u8RefCnt)
|
||||||
OsalMemFree(pstClassifierRulesTable
|
kfree(pstClassifierRulesTable
|
||||||
->stOldPhsRulesList[nClsidIndex].pstPhsRule,
|
->stOldPhsRulesList[nClsidIndex].pstPhsRule);
|
||||||
sizeof(S_PHS_RULE));
|
|
||||||
pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
|
pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
|
||||||
.pstPhsRule = NULL;
|
.pstPhsRule = NULL;
|
||||||
}
|
}
|
||||||
OsalZeroMemory(&pstClassifierRulesTable
|
memset(&pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex], 0, sizeof(S_CLASSIFIER_ENTRY));
|
||||||
->stOldPhsRulesList[nClsidIndex],
|
|
||||||
sizeof(S_CLASSIFIER_ENTRY));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pstServiceFlowEntry->bUsed = FALSE;
|
pstServiceFlowEntry->bUsed = FALSE;
|
||||||
@ -849,7 +844,7 @@ ULONG PhsDeCompress(IN void* pvContext,
|
|||||||
// Does not return any value.
|
// Does not return any value.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable)
|
static void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable)
|
||||||
{
|
{
|
||||||
int i,j;
|
int i,j;
|
||||||
PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
|
PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
|
||||||
@ -876,8 +871,7 @@ void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable)
|
|||||||
->u8RefCnt--;
|
->u8RefCnt--;
|
||||||
if(0==pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule
|
if(0==pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule
|
||||||
->u8RefCnt)
|
->u8RefCnt)
|
||||||
OsalMemFree(pstClassifierRulesTable->stActivePhsRulesList[j].
|
kfree(pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule);
|
||||||
pstPhsRule, sizeof(S_PHS_RULE));
|
|
||||||
pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule = NULL;
|
pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule = NULL;
|
||||||
}
|
}
|
||||||
if(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule)
|
if(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule)
|
||||||
@ -888,24 +882,23 @@ void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable)
|
|||||||
->u8RefCnt--;
|
->u8RefCnt--;
|
||||||
if(0==pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule
|
if(0==pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule
|
||||||
->u8RefCnt)
|
->u8RefCnt)
|
||||||
OsalMemFree(pstClassifierRulesTable->stOldPhsRulesList[j]
|
kfree(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule);
|
||||||
.pstPhsRule,sizeof(S_PHS_RULE));
|
|
||||||
pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule = NULL;
|
pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
OsalMemFree(pstClassifierRulesTable,sizeof(S_CLASSIFIER_TABLE));
|
kfree(pstClassifierRulesTable);
|
||||||
stServiceFlowEntry.pstClassifierTable = pstClassifierRulesTable = NULL;
|
stServiceFlowEntry.pstClassifierTable = pstClassifierRulesTable = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OsalMemFree(psServiceFlowRulesTable,sizeof(S_SERVICEFLOW_TABLE));
|
kfree(psServiceFlowRulesTable);
|
||||||
psServiceFlowRulesTable = NULL;
|
psServiceFlowRulesTable = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BOOLEAN ValidatePHSRuleComplete(IN S_PHS_RULE *psPhsRule)
|
static BOOLEAN ValidatePHSRuleComplete(IN S_PHS_RULE *psPhsRule)
|
||||||
{
|
{
|
||||||
if(psPhsRule)
|
if(psPhsRule)
|
||||||
{
|
{
|
||||||
@ -988,9 +981,9 @@ UINT GetClassifierEntry(IN S_CLASSIFIER_TABLE *pstClassifierTable,
|
|||||||
return PHS_INVALID_TABLE_INDEX;
|
return PHS_INVALID_TABLE_INDEX;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT GetPhsRuleEntry(IN S_CLASSIFIER_TABLE *pstClassifierTable,
|
static UINT GetPhsRuleEntry(IN S_CLASSIFIER_TABLE *pstClassifierTable,
|
||||||
IN B_UINT32 uiPHSI,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,
|
IN B_UINT32 uiPHSI,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,
|
||||||
OUT S_PHS_RULE **ppstPhsRule)
|
OUT S_PHS_RULE **ppstPhsRule)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
S_CLASSIFIER_ENTRY *pstClassifierRule = NULL;
|
S_CLASSIFIER_ENTRY *pstClassifierRule = NULL;
|
||||||
@ -1102,7 +1095,7 @@ UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid,
|
|||||||
if(psPhsRule->u8PHSFLength)
|
if(psPhsRule->u8PHSFLength)
|
||||||
{
|
{
|
||||||
//update PHSF
|
//update PHSF
|
||||||
OsalMemMove(pstClassifierEntry->pstPhsRule->u8PHSF,
|
memcpy(pstClassifierEntry->pstPhsRule->u8PHSF,
|
||||||
psPhsRule->u8PHSF , MAX_PHS_LENGTHS);
|
psPhsRule->u8PHSF , MAX_PHS_LENGTHS);
|
||||||
}
|
}
|
||||||
if(psPhsRule->u8PHSFLength)
|
if(psPhsRule->u8PHSFLength)
|
||||||
@ -1114,7 +1107,7 @@ UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid,
|
|||||||
if(psPhsRule->u8PHSMLength)
|
if(psPhsRule->u8PHSMLength)
|
||||||
{
|
{
|
||||||
//update PHSM
|
//update PHSM
|
||||||
OsalMemMove(pstClassifierEntry->pstPhsRule->u8PHSM,
|
memcpy(pstClassifierEntry->pstPhsRule->u8PHSM,
|
||||||
psPhsRule->u8PHSM, MAX_PHS_LENGTHS);
|
psPhsRule->u8PHSM, MAX_PHS_LENGTHS);
|
||||||
}
|
}
|
||||||
if(psPhsRule->u8PHSMLength)
|
if(psPhsRule->u8PHSMLength)
|
||||||
@ -1147,7 +1140,7 @@ UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid,
|
|||||||
return uiStatus;
|
return uiStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId,
|
static UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId,
|
||||||
S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,
|
S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,
|
||||||
E_CLASSIFIER_ENTRY_CONTEXT eClsContext,B_UINT8 u8AssociatedPHSI)
|
E_CLASSIFIER_ENTRY_CONTEXT eClsContext,B_UINT8 u8AssociatedPHSI)
|
||||||
{
|
{
|
||||||
@ -1234,8 +1227,7 @@ UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId,
|
|||||||
{
|
{
|
||||||
if(psClassifierRules->pstPhsRule == NULL)
|
if(psClassifierRules->pstPhsRule == NULL)
|
||||||
{
|
{
|
||||||
psClassifierRules->pstPhsRule = (S_PHS_RULE*)OsalMemAlloc
|
psClassifierRules->pstPhsRule = kmalloc(sizeof(S_PHS_RULE),GFP_KERNEL);
|
||||||
(sizeof(S_PHS_RULE),PHS_MEM_TAG);
|
|
||||||
|
|
||||||
if(NULL == psClassifierRules->pstPhsRule)
|
if(NULL == psClassifierRules->pstPhsRule)
|
||||||
return ERR_PHSRULE_MEMALLOC_FAIL;
|
return ERR_PHSRULE_MEMALLOC_FAIL;
|
||||||
@ -1247,7 +1239,7 @@ UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId,
|
|||||||
psClassifierRules->bUnclassifiedPHSRule = psPhsRule->bUnclassifiedPHSRule;
|
psClassifierRules->bUnclassifiedPHSRule = psPhsRule->bUnclassifiedPHSRule;
|
||||||
|
|
||||||
/* Update The PHS rule */
|
/* Update The PHS rule */
|
||||||
OsalMemMove(psClassifierRules->pstPhsRule,
|
memcpy(psClassifierRules->pstPhsRule,
|
||||||
psPhsRule, sizeof(S_PHS_RULE));
|
psPhsRule, sizeof(S_PHS_RULE));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1259,7 +1251,7 @@ UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
UINT UpdateClassifierPHSRule(IN B_UINT16 uiClsId,
|
static UINT UpdateClassifierPHSRule(IN B_UINT16 uiClsId,
|
||||||
IN S_CLASSIFIER_ENTRY *pstClassifierEntry,
|
IN S_CLASSIFIER_ENTRY *pstClassifierEntry,
|
||||||
S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,
|
S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,
|
||||||
B_UINT8 u8AssociatedPHSI)
|
B_UINT8 u8AssociatedPHSI)
|
||||||
@ -1289,13 +1281,13 @@ UINT UpdateClassifierPHSRule(IN B_UINT16 uiClsId,
|
|||||||
//Step 2.a PHS Rule Does Not Exist .Create New PHS Rule for uiClsId
|
//Step 2.a PHS Rule Does Not Exist .Create New PHS Rule for uiClsId
|
||||||
if(FALSE == bPHSRuleOrphaned)
|
if(FALSE == bPHSRuleOrphaned)
|
||||||
{
|
{
|
||||||
pstClassifierEntry->pstPhsRule = (S_PHS_RULE*)OsalMemAlloc(sizeof(S_PHS_RULE),PHS_MEM_TAG);
|
pstClassifierEntry->pstPhsRule = kmalloc(sizeof(S_PHS_RULE), GFP_KERNEL);
|
||||||
if(NULL == pstClassifierEntry->pstPhsRule)
|
if(NULL == pstClassifierEntry->pstPhsRule)
|
||||||
{
|
{
|
||||||
return ERR_PHSRULE_MEMALLOC_FAIL;
|
return ERR_PHSRULE_MEMALLOC_FAIL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
OsalMemMove(pstClassifierEntry->pstPhsRule, psPhsRule, sizeof(S_PHS_RULE));
|
memcpy(pstClassifierEntry->pstPhsRule, psPhsRule, sizeof(S_PHS_RULE));
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1304,14 +1296,8 @@ UINT UpdateClassifierPHSRule(IN B_UINT16 uiClsId,
|
|||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nTying Classifier to Existing PHS Rule");
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nTying Classifier to Existing PHS Rule");
|
||||||
if(bPHSRuleOrphaned)
|
if(bPHSRuleOrphaned)
|
||||||
{
|
{
|
||||||
if(pstClassifierEntry->pstPhsRule)
|
kfree(pstClassifierEntry->pstPhsRule);
|
||||||
{
|
|
||||||
//Just Free the PHS Rule as Ref Count is Zero
|
|
||||||
OsalMemFree(pstClassifierEntry->pstPhsRule,sizeof(S_PHS_RULE));
|
|
||||||
pstClassifierEntry->pstPhsRule = NULL;
|
pstClassifierEntry->pstPhsRule = NULL;
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
pstClassifierEntry->pstPhsRule = pstAddPhsRule;
|
pstClassifierEntry->pstPhsRule = pstAddPhsRule;
|
||||||
|
|
||||||
@ -1326,7 +1312,7 @@ UINT UpdateClassifierPHSRule(IN B_UINT16 uiClsId,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN DerefPhsRule(IN B_UINT16 uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable,S_PHS_RULE *pstPhsRule)
|
static BOOLEAN DerefPhsRule(IN B_UINT16 uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable,S_PHS_RULE *pstPhsRule)
|
||||||
{
|
{
|
||||||
if(pstPhsRule==NULL)
|
if(pstPhsRule==NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -1345,22 +1331,6 @@ BOOLEAN DerefPhsRule(IN B_UINT16 uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DumpBuffer(PVOID BuffVAddress, int xferSize)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int iPrintLength;
|
|
||||||
PUCHAR temp=(PUCHAR)BuffVAddress;
|
|
||||||
PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
|
|
||||||
iPrintLength=(xferSize<32?xferSize:32);
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\n");
|
|
||||||
|
|
||||||
for (i=0;i < iPrintLength;i++) {
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "%x|",temp[i]);
|
|
||||||
}
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DumpPhsRules(PPHS_DEVICE_EXTENSION pDeviceExtension)
|
void DumpPhsRules(PPHS_DEVICE_EXTENSION pDeviceExtension)
|
||||||
{
|
{
|
||||||
int i,j,k,l;
|
int i,j,k,l;
|
||||||
@ -1520,8 +1490,8 @@ int phs_decompress(unsigned char *in_buf,unsigned char *out_buf,
|
|||||||
// size-The number of bytes copied into the output buffer i.e dynamic fields
|
// size-The number of bytes copied into the output buffer i.e dynamic fields
|
||||||
// 0 -If PHS rule is NULL.If PHSV field is not set.If the verification fails.
|
// 0 -If PHS rule is NULL.If PHSV field is not set.If the verification fails.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
int phs_compress(S_PHS_RULE *phs_rule,unsigned char *in_buf
|
static int phs_compress(S_PHS_RULE *phs_rule,unsigned char *in_buf
|
||||||
,unsigned char *out_buf,UINT *header_size,UINT *new_header_size)
|
,unsigned char *out_buf,UINT *header_size,UINT *new_header_size)
|
||||||
{
|
{
|
||||||
unsigned char *old_addr = out_buf;
|
unsigned char *old_addr = out_buf;
|
||||||
int supress = 0;
|
int supress = 0;
|
||||||
@ -1581,9 +1551,9 @@ int phs_compress(S_PHS_RULE *phs_rule,unsigned char *in_buf
|
|||||||
// 0 -Packet has failed the verification.
|
// 0 -Packet has failed the verification.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
int verify_suppress_phsf(unsigned char *in_buffer,unsigned char *out_buffer,
|
static int verify_suppress_phsf(unsigned char *in_buffer,unsigned char *out_buffer,
|
||||||
unsigned char *phsf,unsigned char *phsm,unsigned int phss,
|
unsigned char *phsf,unsigned char *phsm,unsigned int phss,
|
||||||
unsigned int phsv,UINT* new_header_size)
|
unsigned int phsv,UINT* new_header_size)
|
||||||
{
|
{
|
||||||
unsigned int size=0;
|
unsigned int size=0;
|
||||||
int bit,i=0;
|
int bit,i=0;
|
||||||
|
@ -27,19 +27,6 @@ void DumpPhsRules(PPHS_DEVICE_EXTENSION pDeviceExtension);
|
|||||||
|
|
||||||
int phs_init(PPHS_DEVICE_EXTENSION pPhsdeviceExtension,PMINI_ADAPTER Adapter);
|
int phs_init(PPHS_DEVICE_EXTENSION pPhsdeviceExtension,PMINI_ADAPTER Adapter);
|
||||||
|
|
||||||
void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable);
|
|
||||||
|
|
||||||
int phs_compress(S_PHS_RULE *phs_members,unsigned char *in_buf,
|
|
||||||
unsigned char *out_buf,unsigned int *header_size,UINT *new_header_size );
|
|
||||||
|
|
||||||
|
|
||||||
int verify_suppress_phsf(unsigned char *in_buffer,unsigned char *out_buffer,
|
|
||||||
unsigned char *phsf,unsigned char *phsm,unsigned int phss,unsigned int phsv,UINT *new_header_size );
|
|
||||||
|
|
||||||
int phs_decompress(unsigned char *in_buf,unsigned char *out_buf,\
|
|
||||||
S_PHS_RULE *phs_rules,UINT *header_size);
|
|
||||||
|
|
||||||
|
|
||||||
int PhsCleanup(PPHS_DEVICE_EXTENSION pPHSDeviceExt);
|
int PhsCleanup(PPHS_DEVICE_EXTENSION pPHSDeviceExt);
|
||||||
|
|
||||||
//Utility Functions
|
//Utility Functions
|
||||||
@ -52,42 +39,10 @@ ULONG PhsDeleteClassifierRule(void* pvContext, B_UINT16 uiVcid ,B_UINT16 uiClsI
|
|||||||
ULONG PhsDeleteSFRules(void* pvContext,B_UINT16 uiVcid) ;
|
ULONG PhsDeleteSFRules(void* pvContext,B_UINT16 uiVcid) ;
|
||||||
|
|
||||||
|
|
||||||
ULONG PhsCompress(void* pvContext,
|
|
||||||
B_UINT16 uiVcid,
|
|
||||||
B_UINT16 uiClsId,
|
|
||||||
void *pvInputBuffer,
|
|
||||||
void *pvOutputBuffer,
|
|
||||||
UINT *pOldHeaderSize,
|
|
||||||
UINT *pNewHeaderSize );
|
|
||||||
|
|
||||||
ULONG PhsDeCompress(void* pvContext,
|
|
||||||
B_UINT16 uiVcid,
|
|
||||||
void *pvInputBuffer,
|
|
||||||
void *pvOutputBuffer,
|
|
||||||
UINT *pInHeaderSize,
|
|
||||||
UINT *pOutHeaderSize);
|
|
||||||
|
|
||||||
|
|
||||||
BOOLEAN ValidatePHSRule(S_PHS_RULE *psPhsRule);
|
BOOLEAN ValidatePHSRule(S_PHS_RULE *psPhsRule);
|
||||||
|
|
||||||
BOOLEAN ValidatePHSRuleComplete(S_PHS_RULE *psPhsRule);
|
|
||||||
|
|
||||||
UINT GetServiceFlowEntry(S_SERVICEFLOW_TABLE *psServiceFlowTable,B_UINT16 uiVcid,S_SERVICEFLOW_ENTRY **ppstServiceFlowEntry);
|
UINT GetServiceFlowEntry(S_SERVICEFLOW_TABLE *psServiceFlowTable,B_UINT16 uiVcid,S_SERVICEFLOW_ENTRY **ppstServiceFlowEntry);
|
||||||
|
|
||||||
UINT GetClassifierEntry(S_CLASSIFIER_TABLE *pstClassifierTable,B_UINT32 uiClsid,E_CLASSIFIER_ENTRY_CONTEXT eClsContext, S_CLASSIFIER_ENTRY **ppstClassifierEntry);
|
|
||||||
|
|
||||||
UINT GetPhsRuleEntry(S_CLASSIFIER_TABLE *pstClassifierTable,B_UINT32 uiPHSI,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,S_PHS_RULE **ppstPhsRule);
|
|
||||||
|
|
||||||
|
|
||||||
UINT CreateSFToClassifierRuleMapping(B_UINT16 uiVcid,B_UINT16 uiClsId,S_SERVICEFLOW_TABLE *psServiceFlowTable,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI);
|
|
||||||
|
|
||||||
UINT CreateClassiferToPHSRuleMapping(B_UINT16 uiVcid,B_UINT16 uiClsId,S_SERVICEFLOW_ENTRY *pstServiceFlowEntry,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI);
|
|
||||||
|
|
||||||
UINT CreateClassifierPHSRule(B_UINT16 uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,B_UINT8 u8AssociatedPHSI);
|
|
||||||
|
|
||||||
UINT UpdateClassifierPHSRule(B_UINT16 uiClsId,S_CLASSIFIER_ENTRY *pstClassifierEntry,S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI);
|
|
||||||
|
|
||||||
BOOLEAN DerefPhsRule(B_UINT16 uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable,S_PHS_RULE *pstPhsRule);
|
|
||||||
|
|
||||||
void DumpPhsRules(PPHS_DEVICE_EXTENSION pDeviceExtension);
|
void DumpPhsRules(PPHS_DEVICE_EXTENSION pDeviceExtension);
|
||||||
|
|
||||||
|
@ -85,10 +85,10 @@ typedef struct _ETH_CS_ETH2_FRAME
|
|||||||
ETH_HEADER_STRUC EThHdr;
|
ETH_HEADER_STRUC EThHdr;
|
||||||
} __attribute__((packed)) ETH_CS_ETH2_FRAME;
|
} __attribute__((packed)) ETH_CS_ETH2_FRAME;
|
||||||
|
|
||||||
|
#define ETHERNET_FRAMETYPE_IPV4 ntohs(0x0800)
|
||||||
|
#define ETHERNET_FRAMETYPE_IPV6 ntohs(0x86dd)
|
||||||
|
#define ETHERNET_FRAMETYPE_802QVLAN ntohs(0x8100)
|
||||||
|
|
||||||
#define ETHERNET_FRAMETYPE_IPV4 ntohs(0x0800)
|
|
||||||
#define ETHERNET_FRAMETYPE_IPV6 ntohs(0x86dd)
|
|
||||||
#define ETHERNET_FRAMETYPE_802QVLAN 0x8100
|
|
||||||
//Per SF CS Specification Encodings
|
//Per SF CS Specification Encodings
|
||||||
typedef enum _E_SERVICEFLOW_CS_SPEC_
|
typedef enum _E_SERVICEFLOW_CS_SPEC_
|
||||||
{
|
{
|
||||||
|
@ -1,23 +1,12 @@
|
|||||||
#ifndef _PROTOTYPES_H_
|
#ifndef _PROTOTYPES_H_
|
||||||
#define _PROTOTYPES_H_
|
#define _PROTOTYPES_H_
|
||||||
|
|
||||||
int BcmFileDownload(PMINI_ADAPTER Adapter,/**< Logical Adapter */
|
|
||||||
char *path, /**< path to image file */
|
|
||||||
unsigned int loc /**< Download Address on the chip*/
|
|
||||||
);
|
|
||||||
VOID LinkControlResponseMessage(PMINI_ADAPTER Adapter, PUCHAR pucBuffer);
|
VOID LinkControlResponseMessage(PMINI_ADAPTER Adapter, PUCHAR pucBuffer);
|
||||||
|
|
||||||
VOID StatisticsResponse(PMINI_ADAPTER Adapter,PVOID pvBuffer);
|
VOID StatisticsResponse(PMINI_ADAPTER Adapter,PVOID pvBuffer);
|
||||||
|
|
||||||
VOID IdleModeResponse(PMINI_ADAPTER Adapter,PUINT puiBuffer);
|
VOID IdleModeResponse(PMINI_ADAPTER Adapter,PUINT puiBuffer);
|
||||||
|
|
||||||
void bcm_kfree_skb(struct sk_buff *skb);
|
|
||||||
VOID bcm_kfree(VOID *ptr);
|
|
||||||
|
|
||||||
|
|
||||||
VOID handle_rx_control_packet(PMINI_ADAPTER Adapter, /**<Pointer to the Adapter structure*/
|
|
||||||
struct sk_buff *skb); /**<Pointer to the socket buffer*/
|
|
||||||
|
|
||||||
int control_packet_handler (PMINI_ADAPTER Adapter);
|
int control_packet_handler (PMINI_ADAPTER Adapter);
|
||||||
|
|
||||||
VOID DeleteAllClassifiersForSF(PMINI_ADAPTER Adapter,UINT uiSearchRuleIndex);
|
VOID DeleteAllClassifiersForSF(PMINI_ADAPTER Adapter,UINT uiSearchRuleIndex);
|
||||||
@ -38,25 +27,16 @@ VOID SortClassifiers(PMINI_ADAPTER Adapter);
|
|||||||
|
|
||||||
VOID flush_all_queues(PMINI_ADAPTER Adapter);
|
VOID flush_all_queues(PMINI_ADAPTER Adapter);
|
||||||
|
|
||||||
USHORT IpVersion4(PMINI_ADAPTER Adapter, /**< Pointer to the driver control structure */
|
|
||||||
struct iphdr *iphd, /**<Pointer to the IP Hdr of the packet*/
|
|
||||||
S_CLASSIFIER_RULE *pstClassifierRule );
|
|
||||||
|
|
||||||
VOID PruneQueue(PMINI_ADAPTER Adapter,/**<Pointer to the driver control structure*/
|
|
||||||
INT iIndex/**<Queue Index*/
|
|
||||||
);
|
|
||||||
|
|
||||||
VOID PruneQueueAllSF(PMINI_ADAPTER Adapter);
|
VOID PruneQueueAllSF(PMINI_ADAPTER Adapter);
|
||||||
|
|
||||||
INT SearchSfid(PMINI_ADAPTER Adapter,UINT uiSfid);
|
INT SearchSfid(PMINI_ADAPTER Adapter,UINT uiSfid);
|
||||||
|
|
||||||
USHORT GetPacketQueueIndex(PMINI_ADAPTER Adapter, /**<Pointer to the driver control structure */
|
USHORT ClassifyPacket(PMINI_ADAPTER Adapter,struct sk_buff* skb);
|
||||||
struct sk_buff* Packet /**< Pointer to the Packet to be sent*/
|
|
||||||
);
|
BOOLEAN MatchSrcPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushSrcPort);
|
||||||
|
BOOLEAN MatchDestPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushSrcPort);
|
||||||
|
BOOLEAN MatchProtocol(S_CLASSIFIER_RULE *pstClassifierRule,UCHAR ucProtocol);
|
||||||
|
|
||||||
VOID
|
|
||||||
reply_to_arp_request(struct sk_buff *skb /**<sk_buff of ARP request*/
|
|
||||||
);
|
|
||||||
|
|
||||||
INT SetupNextSend(PMINI_ADAPTER Adapter, /**<Logical Adapter*/
|
INT SetupNextSend(PMINI_ADAPTER Adapter, /**<Logical Adapter*/
|
||||||
struct sk_buff *Packet, /**<data buffer*/
|
struct sk_buff *Packet, /**<data buffer*/
|
||||||
@ -70,11 +50,9 @@ INT SendControlPacket(PMINI_ADAPTER Adapter, /**<Logical Adapter*/
|
|||||||
char *pControlPacket/**<Control Packet*/
|
char *pControlPacket/**<Control Packet*/
|
||||||
);
|
);
|
||||||
|
|
||||||
INT bcm_transmit(struct sk_buff *skb, /**< skb */
|
|
||||||
struct net_device *dev /**< net device pointer */
|
|
||||||
);
|
|
||||||
|
|
||||||
int register_networkdev(PMINI_ADAPTER Adapter);
|
int register_networkdev(PMINI_ADAPTER Adapter);
|
||||||
|
void unregister_networkdev(PMINI_ADAPTER Adapter);
|
||||||
|
|
||||||
INT AllocAdapterDsxBuffer(PMINI_ADAPTER Adapter);
|
INT AllocAdapterDsxBuffer(PMINI_ADAPTER Adapter);
|
||||||
|
|
||||||
@ -82,8 +60,6 @@ VOID AdapterFree(PMINI_ADAPTER Adapter);
|
|||||||
|
|
||||||
INT FreeAdapterDsxBuffer(PMINI_ADAPTER Adapter);
|
INT FreeAdapterDsxBuffer(PMINI_ADAPTER Adapter);
|
||||||
|
|
||||||
int create_worker_threads(PMINI_ADAPTER psAdapter);
|
|
||||||
|
|
||||||
int tx_pkt_handler(PMINI_ADAPTER Adapter);
|
int tx_pkt_handler(PMINI_ADAPTER Adapter);
|
||||||
|
|
||||||
int reset_card_proc(PMINI_ADAPTER Adapter );
|
int reset_card_proc(PMINI_ADAPTER Adapter );
|
||||||
@ -92,7 +68,6 @@ int run_card_proc(PMINI_ADAPTER Adapter );
|
|||||||
|
|
||||||
int InitCardAndDownloadFirmware(PMINI_ADAPTER ps_adapter);
|
int InitCardAndDownloadFirmware(PMINI_ADAPTER ps_adapter);
|
||||||
|
|
||||||
int bcm_parse_target_params(PMINI_ADAPTER Adapter);
|
|
||||||
|
|
||||||
INT ReadMacAddressFromNVM(PMINI_ADAPTER Adapter);
|
INT ReadMacAddressFromNVM(PMINI_ADAPTER Adapter);
|
||||||
|
|
||||||
@ -110,26 +85,15 @@ int rdmalt (PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t sSize);
|
|||||||
|
|
||||||
int get_dsx_sf_data_to_application(PMINI_ADAPTER Adapter, UINT uiSFId, void __user * user_buffer);
|
int get_dsx_sf_data_to_application(PMINI_ADAPTER Adapter, UINT uiSFId, void __user * user_buffer);
|
||||||
|
|
||||||
void SendLinkDown(PMINI_ADAPTER Adapter);
|
|
||||||
|
|
||||||
void SendIdleModeResponse(PMINI_ADAPTER Adapter);
|
void SendIdleModeResponse(PMINI_ADAPTER Adapter);
|
||||||
|
|
||||||
void HandleShutDownModeRequest(PMINI_ADAPTER Adapter,PUCHAR pucBuffer);
|
|
||||||
|
|
||||||
int ProcessGetHostMibs(PMINI_ADAPTER Adapter, PVOID ioBuffer,
|
int ProcessGetHostMibs(PMINI_ADAPTER Adapter, S_MIBS_HOST_STATS_MIBS *buf);
|
||||||
ULONG inputBufferLength);
|
void GetDroppedAppCntrlPktMibs(S_MIBS_HOST_STATS_MIBS *ioBuffer, PPER_TARANG_DATA pTarang);
|
||||||
|
|
||||||
int GetDroppedAppCntrlPktMibs(PVOID ioBuffer, PPER_TARANG_DATA pTarang);
|
|
||||||
void beceem_parse_target_struct(PMINI_ADAPTER Adapter);
|
void beceem_parse_target_struct(PMINI_ADAPTER Adapter);
|
||||||
|
|
||||||
void doPowerAutoCorrection(PMINI_ADAPTER psAdapter);
|
|
||||||
|
|
||||||
int bcm_ioctl_fw_download(PMINI_ADAPTER Adapter, FIRMWARE_INFO *psFwInfo);
|
int bcm_ioctl_fw_download(PMINI_ADAPTER Adapter, FIRMWARE_INFO *psFwInfo);
|
||||||
|
|
||||||
void bcm_unregister_networkdev(PMINI_ADAPTER Adapter);
|
|
||||||
|
|
||||||
int SearchVcid(PMINI_ADAPTER Adapter,unsigned short usVcid);
|
|
||||||
|
|
||||||
void CopyMIBSExtendedSFParameters(PMINI_ADAPTER Adapter,
|
void CopyMIBSExtendedSFParameters(PMINI_ADAPTER Adapter,
|
||||||
CServiceFlowParamSI *psfLocalSet, UINT uiSearchRuleIndex);
|
CServiceFlowParamSI *psfLocalSet, UINT uiSearchRuleIndex);
|
||||||
|
|
||||||
@ -149,7 +113,6 @@ void update_per_sf_desc_cnts( PMINI_ADAPTER Adapter);
|
|||||||
|
|
||||||
void ClearTargetDSXBuffer(PMINI_ADAPTER Adapter,B_UINT16 TID,BOOLEAN bFreeAll);
|
void ClearTargetDSXBuffer(PMINI_ADAPTER Adapter,B_UINT16 TID,BOOLEAN bFreeAll);
|
||||||
|
|
||||||
void beceem_protocol_reset (PMINI_ADAPTER Adapter);
|
|
||||||
|
|
||||||
void flush_queue(PMINI_ADAPTER Adapter, UINT iQIndex);
|
void flush_queue(PMINI_ADAPTER Adapter, UINT iQIndex);
|
||||||
|
|
||||||
@ -164,31 +127,11 @@ INT BeceemEEPROMBulkRead(
|
|||||||
UINT uiNumBytes);
|
UINT uiNumBytes);
|
||||||
|
|
||||||
|
|
||||||
INT BeceemFlashBulkRead(
|
|
||||||
PMINI_ADAPTER Adapter,
|
|
||||||
PUINT pBuffer,
|
|
||||||
UINT uiOffset,
|
|
||||||
UINT uiNumBytes);
|
|
||||||
|
|
||||||
UINT BcmGetEEPROMSize(PMINI_ADAPTER Adapter);
|
|
||||||
|
|
||||||
INT WriteBeceemEEPROM(PMINI_ADAPTER Adapter,UINT uiEEPROMOffset, UINT uiData);
|
INT WriteBeceemEEPROM(PMINI_ADAPTER Adapter,UINT uiEEPROMOffset, UINT uiData);
|
||||||
|
|
||||||
UINT BcmGetFlashSize(PMINI_ADAPTER Adapter);
|
|
||||||
|
|
||||||
UINT BcmGetFlashSectorSize(PMINI_ADAPTER Adapter, UINT FlashSectorSizeSig, UINT FlashSectorSize);
|
|
||||||
|
|
||||||
INT BeceemFlashBulkWrite(
|
|
||||||
PMINI_ADAPTER Adapter,
|
|
||||||
PUINT pBuffer,
|
|
||||||
UINT uiOffset,
|
|
||||||
UINT uiNumBytes,
|
|
||||||
BOOLEAN bVerify);
|
|
||||||
|
|
||||||
INT PropagateCalParamsFromFlashToMemory(PMINI_ADAPTER Adapter);
|
INT PropagateCalParamsFromFlashToMemory(PMINI_ADAPTER Adapter);
|
||||||
|
|
||||||
INT PropagateCalParamsFromEEPROMToMemory(PMINI_ADAPTER Adapter);
|
|
||||||
|
|
||||||
|
|
||||||
INT BeceemEEPROMBulkWrite(
|
INT BeceemEEPROMBulkWrite(
|
||||||
PMINI_ADAPTER Adapter,
|
PMINI_ADAPTER Adapter,
|
||||||
@ -198,11 +141,8 @@ INT BeceemEEPROMBulkWrite(
|
|||||||
BOOLEAN bVerify);
|
BOOLEAN bVerify);
|
||||||
|
|
||||||
|
|
||||||
INT ReadBeceemEEPROMBulk(PMINI_ADAPTER Adapter,UINT dwAddress, UINT *pdwData, UINT dwNumData);
|
|
||||||
|
|
||||||
INT ReadBeceemEEPROM(PMINI_ADAPTER Adapter,UINT dwAddress, UINT *pdwData);
|
INT ReadBeceemEEPROM(PMINI_ADAPTER Adapter,UINT dwAddress, UINT *pdwData);
|
||||||
|
|
||||||
NVM_TYPE BcmGetNvmType(PMINI_ADAPTER Adapter);
|
|
||||||
|
|
||||||
INT BeceemNVMRead(
|
INT BeceemNVMRead(
|
||||||
PMINI_ADAPTER Adapter,
|
PMINI_ADAPTER Adapter,
|
||||||
@ -217,24 +157,12 @@ INT BeceemNVMWrite(
|
|||||||
UINT uiNumBytes,
|
UINT uiNumBytes,
|
||||||
BOOLEAN bVerify);
|
BOOLEAN bVerify);
|
||||||
|
|
||||||
INT BcmUpdateSectorSize(PMINI_ADAPTER Adapter,UINT uiSectorSize);
|
|
||||||
|
|
||||||
INT BcmInitNVM(PMINI_ADAPTER Adapter);
|
INT BcmInitNVM(PMINI_ADAPTER Adapter);
|
||||||
|
|
||||||
INT BcmGetNvmSize(PMINI_ADAPTER Adapter);
|
INT BcmUpdateSectorSize(PMINI_ADAPTER Adapter,UINT uiSectorSize);
|
||||||
|
BOOLEAN IsSectionExistInFlash(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL section);
|
||||||
|
|
||||||
INT IsSectionExistInVendorInfo(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL section);
|
|
||||||
|
|
||||||
VOID BcmValidateNvmType(PMINI_ADAPTER Adapter);
|
|
||||||
|
|
||||||
VOID ConfigureEndPointTypesThroughEEPROM(PMINI_ADAPTER Adapter);
|
|
||||||
|
|
||||||
INT BcmGetFlashCSInfo(PMINI_ADAPTER Adapter);
|
|
||||||
INT ReadDSDHeader(PMINI_ADAPTER Adapter, PDSD_HEADER psDSDHeader, FLASH2X_SECTION_VAL dsd);
|
|
||||||
INT BcmGetActiveDSD(PMINI_ADAPTER Adapter);
|
|
||||||
INT ReadISOHeader(PMINI_ADAPTER Adapter, PISO_HEADER psISOHeader, FLASH2X_SECTION_VAL IsoImage);
|
|
||||||
INT BcmGetActiveISO(PMINI_ADAPTER Adapter);
|
|
||||||
B_UINT8 IsOffsetWritable(PMINI_ADAPTER Adapter, UINT uiOffset);
|
|
||||||
INT BcmGetFlash2xSectionalBitMap(PMINI_ADAPTER Adapter, PFLASH2X_BITMAP psFlash2xBitMap);
|
INT BcmGetFlash2xSectionalBitMap(PMINI_ADAPTER Adapter, PFLASH2X_BITMAP psFlash2xBitMap);
|
||||||
|
|
||||||
INT BcmFlash2xBulkWrite(
|
INT BcmFlash2xBulkWrite(
|
||||||
@ -251,7 +179,6 @@ INT BcmFlash2xBulkRead(
|
|||||||
FLASH2X_SECTION_VAL eFlashSectionVal,
|
FLASH2X_SECTION_VAL eFlashSectionVal,
|
||||||
UINT uiOffsetWithinSectionVal,
|
UINT uiOffsetWithinSectionVal,
|
||||||
UINT uiNumBytes);
|
UINT uiNumBytes);
|
||||||
INT BcmGetSectionValEndOffset(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlashSectionVal);
|
|
||||||
|
|
||||||
INT BcmGetSectionValStartOffset(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlashSectionVal);
|
INT BcmGetSectionValStartOffset(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlashSectionVal);
|
||||||
|
|
||||||
@ -264,34 +191,13 @@ INT BcmFlash2xCorruptSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSect
|
|||||||
INT BcmFlash2xWriteSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlashSectionVal);
|
INT BcmFlash2xWriteSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlashSectionVal);
|
||||||
INT validateFlash2xReadWrite(PMINI_ADAPTER Adapter, PFLASH2X_READWRITE psFlash2xReadWrite);
|
INT validateFlash2xReadWrite(PMINI_ADAPTER Adapter, PFLASH2X_READWRITE psFlash2xReadWrite);
|
||||||
INT IsFlash2x(PMINI_ADAPTER Adapter);
|
INT IsFlash2x(PMINI_ADAPTER Adapter);
|
||||||
INT GetFlashBaseAddr(PMINI_ADAPTER Adapter);
|
|
||||||
INT SaveHeaderIfPresent(PMINI_ADAPTER Adapter, PUCHAR pBuff, UINT uiSectAlignAddr);
|
|
||||||
INT BcmCopySection(PMINI_ADAPTER Adapter,
|
INT BcmCopySection(PMINI_ADAPTER Adapter,
|
||||||
FLASH2X_SECTION_VAL SrcSection,
|
FLASH2X_SECTION_VAL SrcSection,
|
||||||
FLASH2X_SECTION_VAL DstSection,
|
FLASH2X_SECTION_VAL DstSection,
|
||||||
UINT offset,
|
UINT offset,
|
||||||
UINT numOfBytes);
|
UINT numOfBytes);
|
||||||
|
|
||||||
INT BcmDoChipSelect(PMINI_ADAPTER Adapter, UINT offset);
|
|
||||||
INT BcmMakeFlashCSActive(PMINI_ADAPTER Adapter, UINT offset);
|
|
||||||
INT ReadDSDSignature(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL dsd);
|
|
||||||
INT ReadDSDPriority(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL dsd);
|
|
||||||
FLASH2X_SECTION_VAL getHighestPriDSD(PMINI_ADAPTER Adapter);
|
|
||||||
INT ReadISOSignature(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL iso);
|
|
||||||
INT ReadISOPriority(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL iso);
|
|
||||||
FLASH2X_SECTION_VAL getHighestPriISO(PMINI_ADAPTER Adapter);
|
|
||||||
INT WriteToFlashWithoutSectorErase(PMINI_ADAPTER Adapter,
|
|
||||||
PUINT pBuff,
|
|
||||||
FLASH2X_SECTION_VAL eFlash2xSectionVal,
|
|
||||||
UINT uiOffset,
|
|
||||||
UINT uiNumBytes
|
|
||||||
);
|
|
||||||
|
|
||||||
//UINT getNumOfSubSectionWithWRPermisson(PMINI_ADAPTER Adapter, SECTION_TYPE secType);
|
|
||||||
BOOLEAN IsSectionExistInFlash(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL section);
|
|
||||||
INT IsSectionWritable(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL Section);
|
|
||||||
INT CorruptDSDSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal);
|
|
||||||
INT CorruptISOSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal);
|
|
||||||
BOOLEAN IsNonCDLessDevice(PMINI_ADAPTER Adapter);
|
BOOLEAN IsNonCDLessDevice(PMINI_ADAPTER Adapter);
|
||||||
|
|
||||||
|
|
||||||
@ -300,7 +206,6 @@ VOID OverrideServiceFlowParams(PMINI_ADAPTER Adapter,PUINT puiBuffer);
|
|||||||
int wrmaltWithLock (PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t sSize);
|
int wrmaltWithLock (PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t sSize);
|
||||||
int rdmaltWithLock (PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t sSize);
|
int rdmaltWithLock (PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t sSize);
|
||||||
|
|
||||||
int rdmWithLock(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t size);
|
|
||||||
int wrmWithLock(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t size);
|
int wrmWithLock(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t size);
|
||||||
INT buffDnldVerify(PMINI_ADAPTER Adapter, unsigned char *mappedbuffer, unsigned int u32FirmwareLength,
|
INT buffDnldVerify(PMINI_ADAPTER Adapter, unsigned char *mappedbuffer, unsigned int u32FirmwareLength,
|
||||||
unsigned long u32StartingAddress);
|
unsigned long u32StartingAddress);
|
||||||
@ -309,11 +214,6 @@ INT buffDnldVerify(PMINI_ADAPTER Adapter, unsigned char *mappedbuffer, unsigned
|
|||||||
VOID putUsbSuspend(struct work_struct *work);
|
VOID putUsbSuspend(struct work_struct *work);
|
||||||
BOOLEAN IsReqGpioIsLedInNVM(PMINI_ADAPTER Adapter, UINT gpios);
|
BOOLEAN IsReqGpioIsLedInNVM(PMINI_ADAPTER Adapter, UINT gpios);
|
||||||
|
|
||||||
#ifdef BCM_SHM_INTERFACE
|
|
||||||
INT beceem_virtual_device_init(void);
|
|
||||||
VOID virtual_mail_box_interrupt(void);
|
|
||||||
INT beceem_virtual_device_exit(void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -4,15 +4,14 @@ This file contains the routines related to Quality of Service.
|
|||||||
*/
|
*/
|
||||||
#include "headers.h"
|
#include "headers.h"
|
||||||
|
|
||||||
BOOLEAN MatchSrcIpAddress(S_CLASSIFIER_RULE *pstClassifierRule,ULONG ulSrcIP);
|
static void EThCSGetPktInfo(PMINI_ADAPTER Adapter,PVOID pvEthPayload,PS_ETHCS_PKT_INFO pstEthCsPktInfo);
|
||||||
BOOLEAN MatchTos(S_CLASSIFIER_RULE *pstClassifierRule,UCHAR ucTypeOfService);
|
static BOOLEAN EThCSClassifyPkt(PMINI_ADAPTER Adapter,struct sk_buff* skb,PS_ETHCS_PKT_INFO pstEthCsPktInfo,S_CLASSIFIER_RULE *pstClassifierRule, B_UINT8 EthCSCupport);
|
||||||
BOOLEAN MatchSrcPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushSrcPort);
|
|
||||||
BOOLEAN MatchDestPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushDestPort);
|
static USHORT IpVersion4(PMINI_ADAPTER Adapter, struct iphdr *iphd,
|
||||||
BOOLEAN MatchProtocol(S_CLASSIFIER_RULE *pstClassifierRule,UCHAR ucProtocol);
|
S_CLASSIFIER_RULE *pstClassifierRule );
|
||||||
BOOLEAN MatchDestIpAddress(S_CLASSIFIER_RULE *pstClassifierRule,ULONG ulDestIP);
|
|
||||||
USHORT ClassifyPacket(PMINI_ADAPTER Adapter,struct sk_buff* skb);
|
static VOID PruneQueue(PMINI_ADAPTER Adapter, INT iIndex);
|
||||||
void EThCSGetPktInfo(PMINI_ADAPTER Adapter,PVOID pvEthPayload,PS_ETHCS_PKT_INFO pstEthCsPktInfo);
|
|
||||||
BOOLEAN EThCSClassifyPkt(PMINI_ADAPTER Adapter,struct sk_buff* skb,PS_ETHCS_PKT_INFO pstEthCsPktInfo,S_CLASSIFIER_RULE *pstClassifierRule, B_UINT8 EthCSCupport);
|
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
* Function - MatchSrcIpAddress()
|
* Function - MatchSrcIpAddress()
|
||||||
@ -205,11 +204,10 @@ BOOLEAN MatchDestPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushDestPort)
|
|||||||
Compares IPV4 Ip address and port number
|
Compares IPV4 Ip address and port number
|
||||||
@return Queue Index.
|
@return Queue Index.
|
||||||
*/
|
*/
|
||||||
USHORT IpVersion4(PMINI_ADAPTER Adapter, /**< Pointer to the driver control structure */
|
static USHORT IpVersion4(PMINI_ADAPTER Adapter,
|
||||||
struct iphdr *iphd, /**<Pointer to the IP Hdr of the packet*/
|
struct iphdr *iphd,
|
||||||
S_CLASSIFIER_RULE *pstClassifierRule )
|
S_CLASSIFIER_RULE *pstClassifierRule )
|
||||||
{
|
{
|
||||||
//IPHeaderFormat *pIpHeader=NULL;
|
|
||||||
xporthdr *xprt_hdr=NULL;
|
xporthdr *xprt_hdr=NULL;
|
||||||
BOOLEAN bClassificationSucceed=FALSE;
|
BOOLEAN bClassificationSucceed=FALSE;
|
||||||
|
|
||||||
@ -261,15 +259,6 @@ USHORT IpVersion4(PMINI_ADAPTER Adapter, /**< Pointer to the driver control stru
|
|||||||
//if protocol is not TCP or UDP then no need of comparing source port and destination port
|
//if protocol is not TCP or UDP then no need of comparing source port and destination port
|
||||||
if(iphd->protocol!=TCP && iphd->protocol!=UDP)
|
if(iphd->protocol!=TCP && iphd->protocol!=UDP)
|
||||||
break;
|
break;
|
||||||
#if 0
|
|
||||||
//check if memory is available of src and Dest port
|
|
||||||
if(ETH_AND_IP_HEADER_LEN + L4_SRC_PORT_LEN + L4_DEST_PORT_LEN > Packet->len)
|
|
||||||
{
|
|
||||||
//This is not an erroneous condition and pkt will be checked for next classification.
|
|
||||||
bClassificationSucceed = FALSE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
//******************Checking Transport Layer Header field if present *****************//
|
//******************Checking Transport Layer Header field if present *****************//
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Source Port %04x",
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Source Port %04x",
|
||||||
(iphd->protocol==UDP)?xprt_hdr->uhdr.source:xprt_hdr->thdr.source);
|
(iphd->protocol==UDP)?xprt_hdr->uhdr.source:xprt_hdr->thdr.source);
|
||||||
@ -312,29 +301,6 @@ USHORT IpVersion4(PMINI_ADAPTER Adapter, /**< Pointer to the driver control stru
|
|||||||
|
|
||||||
return bClassificationSucceed;
|
return bClassificationSucceed;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
@ingroup tx_functions
|
|
||||||
@return Queue Index based on priority.
|
|
||||||
*/
|
|
||||||
USHORT GetPacketQueueIndex(PMINI_ADAPTER Adapter, /**<Pointer to the driver control structure */
|
|
||||||
struct sk_buff* Packet /**< Pointer to the Packet to be sent*/
|
|
||||||
)
|
|
||||||
{
|
|
||||||
USHORT usIndex=-1;
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, QUEUE_INDEX, DBG_LVL_ALL, "=====>");
|
|
||||||
|
|
||||||
if(NULL==Adapter || NULL==Packet)
|
|
||||||
{
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, QUEUE_INDEX, DBG_LVL_ALL, "Got NULL Values<======");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
usIndex = ClassifyPacket(Adapter,Packet);
|
|
||||||
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, QUEUE_INDEX, DBG_LVL_ALL, "Got Queue Index %x",usIndex);
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, QUEUE_INDEX, DBG_LVL_ALL, "GetPacketQueueIndex <==============");
|
|
||||||
return usIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID PruneQueueAllSF(PMINI_ADAPTER Adapter)
|
VOID PruneQueueAllSF(PMINI_ADAPTER Adapter)
|
||||||
{
|
{
|
||||||
@ -357,23 +323,21 @@ is less than number of bytes in the queue. If so -
|
|||||||
drops packets from the Head till the number of bytes is
|
drops packets from the Head till the number of bytes is
|
||||||
less than or equal to max queue size for the queue.
|
less than or equal to max queue size for the queue.
|
||||||
*/
|
*/
|
||||||
VOID PruneQueue(PMINI_ADAPTER Adapter,/**<Pointer to the driver control structure*/
|
static VOID PruneQueue(PMINI_ADAPTER Adapter, INT iIndex)
|
||||||
INT iIndex/**<Queue Index*/
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
struct sk_buff* PacketToDrop=NULL;
|
struct sk_buff* PacketToDrop=NULL;
|
||||||
struct net_device_stats* netstats=NULL;
|
struct net_device_stats *netstats;
|
||||||
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, PRUNE_QUEUE, DBG_LVL_ALL, "=====> Index %d",iIndex);
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, PRUNE_QUEUE, DBG_LVL_ALL, "=====> Index %d",iIndex);
|
||||||
|
|
||||||
if(iIndex == HiPriority)
|
if(iIndex == HiPriority)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(!Adapter || (iIndex < 0) || (iIndex > HiPriority))
|
if(!Adapter || (iIndex < 0) || (iIndex > HiPriority))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* To Store the netdevice statistic */
|
/* To Store the netdevice statistic */
|
||||||
netstats = &((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats;
|
netstats = &Adapter->dev->stats;
|
||||||
|
|
||||||
spin_lock_bh(&Adapter->PackInfo[iIndex].SFQueueLock);
|
spin_lock_bh(&Adapter->PackInfo[iIndex].SFQueueLock);
|
||||||
|
|
||||||
@ -395,9 +359,13 @@ VOID PruneQueue(PMINI_ADAPTER Adapter,/**<Pointer to the driver control structur
|
|||||||
|
|
||||||
if(PacketToDrop)
|
if(PacketToDrop)
|
||||||
{
|
{
|
||||||
if(netstats)
|
struct netdev_queue *txq = netdev_get_tx_queue(Adapter->dev, iIndex);
|
||||||
netstats->tx_dropped++;
|
if (netif_msg_tx_err(Adapter))
|
||||||
atomic_inc(&Adapter->TxDroppedPacketCount);
|
pr_info(PFX "%s: tx queue %d overlimit\n",
|
||||||
|
Adapter->dev->name, iIndex);
|
||||||
|
|
||||||
|
txq->tx_dropped++;
|
||||||
|
|
||||||
DEQUEUEPACKET(Adapter->PackInfo[iIndex].FirstTxQueue,
|
DEQUEUEPACKET(Adapter->PackInfo[iIndex].FirstTxQueue,
|
||||||
Adapter->PackInfo[iIndex].LastTxQueue);
|
Adapter->PackInfo[iIndex].LastTxQueue);
|
||||||
/// update current bytes and packets count
|
/// update current bytes and packets count
|
||||||
@ -407,7 +375,7 @@ VOID PruneQueue(PMINI_ADAPTER Adapter,/**<Pointer to the driver control structur
|
|||||||
/// update dropped bytes and packets counts
|
/// update dropped bytes and packets counts
|
||||||
Adapter->PackInfo[iIndex].uiDroppedCountBytes += PacketToDrop->len;
|
Adapter->PackInfo[iIndex].uiDroppedCountBytes += PacketToDrop->len;
|
||||||
Adapter->PackInfo[iIndex].uiDroppedCountPackets++;
|
Adapter->PackInfo[iIndex].uiDroppedCountPackets++;
|
||||||
bcm_kfree_skb(PacketToDrop);
|
dev_kfree_skb(PacketToDrop);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -416,7 +384,6 @@ VOID PruneQueue(PMINI_ADAPTER Adapter,/**<Pointer to the driver control structur
|
|||||||
Adapter->PackInfo[iIndex].uiDroppedCountPackets);
|
Adapter->PackInfo[iIndex].uiDroppedCountPackets);
|
||||||
|
|
||||||
atomic_dec(&Adapter->TotalPacketCount);
|
atomic_dec(&Adapter->TotalPacketCount);
|
||||||
Adapter->bcm_jiffies = jiffies;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_unlock_bh(&Adapter->PackInfo[iIndex].SFQueueLock);
|
spin_unlock_bh(&Adapter->PackInfo[iIndex].SFQueueLock);
|
||||||
@ -430,16 +397,15 @@ VOID flush_all_queues(PMINI_ADAPTER Adapter)
|
|||||||
{
|
{
|
||||||
INT iQIndex;
|
INT iQIndex;
|
||||||
UINT uiTotalPacketLength;
|
UINT uiTotalPacketLength;
|
||||||
struct sk_buff* PacketToDrop=NULL;
|
struct sk_buff* PacketToDrop=NULL;
|
||||||
struct net_device_stats* netstats=NULL;
|
|
||||||
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "=====>");
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "=====>");
|
||||||
/* To Store the netdevice statistic */
|
|
||||||
netstats = &((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats;
|
|
||||||
|
|
||||||
// down(&Adapter->data_packet_queue_lock);
|
// down(&Adapter->data_packet_queue_lock);
|
||||||
for(iQIndex=LowPriority; iQIndex<HiPriority; iQIndex++)
|
for(iQIndex=LowPriority; iQIndex<HiPriority; iQIndex++)
|
||||||
{
|
{
|
||||||
|
struct netdev_queue *txq = netdev_get_tx_queue(Adapter->dev, iQIndex);
|
||||||
|
|
||||||
spin_lock_bh(&Adapter->PackInfo[iQIndex].SFQueueLock);
|
spin_lock_bh(&Adapter->PackInfo[iQIndex].SFQueueLock);
|
||||||
while(Adapter->PackInfo[iQIndex].FirstTxQueue)
|
while(Adapter->PackInfo[iQIndex].FirstTxQueue)
|
||||||
{
|
{
|
||||||
@ -447,8 +413,7 @@ VOID flush_all_queues(PMINI_ADAPTER Adapter)
|
|||||||
if(PacketToDrop)
|
if(PacketToDrop)
|
||||||
{
|
{
|
||||||
uiTotalPacketLength = PacketToDrop->len;
|
uiTotalPacketLength = PacketToDrop->len;
|
||||||
netstats->tx_dropped++;
|
txq->tx_dropped++;
|
||||||
atomic_inc(&Adapter->TxDroppedPacketCount);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
uiTotalPacketLength = 0;
|
uiTotalPacketLength = 0;
|
||||||
@ -457,7 +422,7 @@ VOID flush_all_queues(PMINI_ADAPTER Adapter)
|
|||||||
Adapter->PackInfo[iQIndex].LastTxQueue);
|
Adapter->PackInfo[iQIndex].LastTxQueue);
|
||||||
|
|
||||||
/* Free the skb */
|
/* Free the skb */
|
||||||
bcm_kfree_skb(PacketToDrop);
|
dev_kfree_skb(PacketToDrop);
|
||||||
|
|
||||||
/// update current bytes and packets count
|
/// update current bytes and packets count
|
||||||
Adapter->PackInfo[iQIndex].uiCurrentBytesOnHost -= uiTotalPacketLength;
|
Adapter->PackInfo[iQIndex].uiCurrentBytesOnHost -= uiTotalPacketLength;
|
||||||
@ -559,12 +524,6 @@ USHORT ClassifyPacket(PMINI_ADAPTER Adapter,struct sk_buff* skb)
|
|||||||
|
|
||||||
for(uiLoopIndex = MAX_CLASSIFIERS - 1; uiLoopIndex >= 0; uiLoopIndex--)
|
for(uiLoopIndex = MAX_CLASSIFIERS - 1; uiLoopIndex >= 0; uiLoopIndex--)
|
||||||
{
|
{
|
||||||
if (Adapter->device_removed)
|
|
||||||
{
|
|
||||||
bClassificationSucceed = FALSE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(bClassificationSucceed)
|
if(bClassificationSucceed)
|
||||||
break;
|
break;
|
||||||
//Iterate through all classifiers which are already in order of priority
|
//Iterate through all classifiers which are already in order of priority
|
||||||
@ -810,7 +769,10 @@ static BOOLEAN EthCSMatchVLANRules(S_CLASSIFIER_RULE *pstClassifierRule,struct s
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BOOLEAN EThCSClassifyPkt(PMINI_ADAPTER Adapter,struct sk_buff* skb,PS_ETHCS_PKT_INFO pstEthCsPktInfo,S_CLASSIFIER_RULE *pstClassifierRule, B_UINT8 EthCSCupport)
|
static BOOLEAN EThCSClassifyPkt(PMINI_ADAPTER Adapter,struct sk_buff* skb,
|
||||||
|
PS_ETHCS_PKT_INFO pstEthCsPktInfo,
|
||||||
|
S_CLASSIFIER_RULE *pstClassifierRule,
|
||||||
|
B_UINT8 EthCSCupport)
|
||||||
{
|
{
|
||||||
BOOLEAN bClassificationSucceed = FALSE;
|
BOOLEAN bClassificationSucceed = FALSE;
|
||||||
bClassificationSucceed = EthCSMatchSrcMACAddress(pstClassifierRule,((ETH_HEADER_STRUC *)(skb->data))->au8SourceAddress);
|
bClassificationSucceed = EthCSMatchSrcMACAddress(pstClassifierRule,((ETH_HEADER_STRUC *)(skb->data))->au8SourceAddress);
|
||||||
@ -840,9 +802,11 @@ BOOLEAN EThCSClassifyPkt(PMINI_ADAPTER Adapter,struct sk_buff* skb,PS_ETHCS_PKT_
|
|||||||
return bClassificationSucceed;
|
return bClassificationSucceed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EThCSGetPktInfo(PMINI_ADAPTER Adapter,PVOID pvEthPayload,PS_ETHCS_PKT_INFO pstEthCsPktInfo)
|
static void EThCSGetPktInfo(PMINI_ADAPTER Adapter,PVOID pvEthPayload,
|
||||||
|
PS_ETHCS_PKT_INFO pstEthCsPktInfo)
|
||||||
{
|
{
|
||||||
USHORT u16Etype = ntohs(((ETH_HEADER_STRUC*)pvEthPayload)->u16Etype);
|
USHORT u16Etype = ntohs(((ETH_HEADER_STRUC*)pvEthPayload)->u16Etype);
|
||||||
|
|
||||||
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "EthCSGetPktInfo : Eth Hdr Type : %X\n",u16Etype);
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "EthCSGetPktInfo : Eth Hdr Type : %X\n",u16Etype);
|
||||||
if(u16Etype > 0x5dc)
|
if(u16Etype > 0x5dc)
|
||||||
{
|
{
|
||||||
|
@ -1,15 +1,22 @@
|
|||||||
|
This driver is barely functional in its current state.
|
||||||
|
|
||||||
|
BIG:
|
||||||
|
- existing API is (/dev/tarang) should be replaced
|
||||||
|
Is it possible to use same API as Intel Wimax stack and
|
||||||
|
have same user level components.
|
||||||
|
- Qos and queue model is non-standard and inflexible.
|
||||||
|
Use existing TC Qos?
|
||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
|
- support more than one board - eliminate global variables
|
||||||
|
- remove developer debug BCM_DEBUG() macros
|
||||||
|
add a limited number of messages through netif_msg()
|
||||||
- fix non-standard kernel style
|
- fix non-standard kernel style
|
||||||
- sparse warnings
|
|
||||||
- checkpatch warnings
|
- checkpatch warnings
|
||||||
- remove compatiablity code for older kernels
|
- use request firmware
|
||||||
- remove #ifdef's
|
- fix use of file I/O to load config with better API
|
||||||
- fix bogus device nameing and reference counting (see bcm_notify_event)
|
- merge some files together?
|
||||||
- fix use of file I/O to load config
|
|
||||||
- request firmware
|
|
||||||
- update to current network device API
|
|
||||||
- merge some files together
|
|
||||||
- cleanup/eliminate debug messages
|
- cleanup/eliminate debug messages
|
||||||
|
|
||||||
- integrate with existing Wimax stack?
|
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
digraph transmit1 {
|
digraph transmit1 {
|
||||||
node[shape=box]
|
node[shape=box]
|
||||||
edge[weight=5;color=red]
|
edge[weight=5;color=red]
|
||||||
bcm_transmit->reply_to_arp_request[label="ARP"]
|
|
||||||
bcm_transmit->GetPacketQueueIndex[label="IP Packet"]
|
bcm_transmit->GetPacketQueueIndex[label="IP Packet"]
|
||||||
GetPacketQueueIndex->IpVersion4[label="IPV4"]
|
GetPacketQueueIndex->IpVersion4[label="IPV4"]
|
||||||
GetPacketQueueIndex->IpVersion6[label="IPV6"]
|
GetPacketQueueIndex->IpVersion6[label="IPV6"]
|
||||||
@ -35,169 +35,16 @@ SendPacketFromQueue->SetupNextSend->bcm_cmd53
|
|||||||
|
|
||||||
#include "headers.h"
|
#include "headers.h"
|
||||||
|
|
||||||
/*******************************************************************
|
|
||||||
* Function - bcm_transmit()
|
|
||||||
*
|
|
||||||
* Description - This is the main transmit function for our virtual
|
|
||||||
* interface(veth0). It handles the ARP packets. It
|
|
||||||
* clones this packet and then Queue it to a suitable
|
|
||||||
* Queue. Then calls the transmit_packet().
|
|
||||||
*
|
|
||||||
* Parameter - skb - Pointer to the socket buffer structure
|
|
||||||
* dev - Pointer to the virtual net device structure
|
|
||||||
*
|
|
||||||
* Returns - zero (success) or -ve value (failure)
|
|
||||||
*
|
|
||||||
*********************************************************************/
|
|
||||||
|
|
||||||
INT bcm_transmit(struct sk_buff *skb, /**< skb */
|
|
||||||
struct net_device *dev /**< net device pointer */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
PMINI_ADAPTER Adapter = NULL;
|
|
||||||
USHORT qindex=0;
|
|
||||||
struct timeval tv;
|
|
||||||
UINT pkt_type = 0;
|
|
||||||
UINT calltransmit = 0;
|
|
||||||
|
|
||||||
BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "\n%s====>\n",__FUNCTION__);
|
|
||||||
|
|
||||||
memset(&tv, 0, sizeof(tv));
|
|
||||||
/* Check for valid parameters */
|
|
||||||
if(skb == NULL || dev==NULL)
|
|
||||||
{
|
|
||||||
BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX,TX_OSAL_DBG, DBG_LVL_ALL, "Got NULL skb or dev\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
Adapter = GET_BCM_ADAPTER(dev);
|
|
||||||
if(!Adapter)
|
|
||||||
{
|
|
||||||
BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "Got Invalid Adapter\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
if(Adapter->device_removed == TRUE || !Adapter->LinkUpStatus)
|
|
||||||
{
|
|
||||||
if(!netif_queue_stopped(dev)) {
|
|
||||||
netif_carrier_off(dev);
|
|
||||||
netif_stop_queue(dev);
|
|
||||||
}
|
|
||||||
return STATUS_FAILURE;
|
|
||||||
}
|
|
||||||
BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "Packet size : %d\n", skb->len);
|
|
||||||
|
|
||||||
/*Add Ethernet CS check here*/
|
|
||||||
if(Adapter->TransferMode == IP_PACKET_ONLY_MODE )
|
|
||||||
{
|
|
||||||
pkt_type = ntohs(*(PUSHORT)(skb->data + 12));
|
|
||||||
/* Get the queue index where the packet is to be queued */
|
|
||||||
BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "Getting the Queue Index.....");
|
|
||||||
|
|
||||||
qindex = GetPacketQueueIndex(Adapter,skb);
|
|
||||||
|
|
||||||
if((SHORT)INVALID_QUEUE_INDEX==(SHORT)qindex)
|
|
||||||
{
|
|
||||||
if(pkt_type == ETH_ARP_FRAME)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Reply directly to ARP request packet
|
|
||||||
ARP Spoofing only if NO ETH CS rule matches for it
|
|
||||||
*/
|
|
||||||
BCM_DEBUG_PRINT (Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL,"ARP OPCODE = %02x",
|
|
||||||
|
|
||||||
(*(PUCHAR)(skb->data + 21)));
|
|
||||||
|
|
||||||
reply_to_arp_request(skb);
|
|
||||||
|
|
||||||
BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX,TX_OSAL_DBG, DBG_LVL_ALL,"After reply_to_arp_request \n");
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL,
|
|
||||||
"Invalid queue index, dropping pkt\n");
|
|
||||||
|
|
||||||
bcm_kfree_skb(skb);
|
|
||||||
}
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Adapter->PackInfo[qindex].uiCurrentPacketsOnHost >= SF_MAX_ALLOWED_PACKETS_TO_BACKUP)
|
|
||||||
{
|
|
||||||
atomic_inc(&Adapter->TxDroppedPacketCount);
|
|
||||||
bcm_kfree_skb(skb);
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now Enqueue the packet */
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "bcm_transmit Enqueueing the Packet To Queue %d",qindex);
|
|
||||||
spin_lock(&Adapter->PackInfo[qindex].SFQueueLock);
|
|
||||||
Adapter->PackInfo[qindex].uiCurrentBytesOnHost += skb->len;
|
|
||||||
Adapter->PackInfo[qindex].uiCurrentPacketsOnHost++;
|
|
||||||
|
|
||||||
*((B_UINT32 *)skb->cb + SKB_CB_LATENCY_OFFSET ) = jiffies;
|
|
||||||
ENQUEUEPACKET(Adapter->PackInfo[qindex].FirstTxQueue,
|
|
||||||
Adapter->PackInfo[qindex].LastTxQueue, skb);
|
|
||||||
atomic_inc(&Adapter->TotalPacketCount);
|
|
||||||
spin_unlock(&Adapter->PackInfo[qindex].SFQueueLock);
|
|
||||||
do_gettimeofday(&tv);
|
|
||||||
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL,"ENQ: \n");
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "Pkt Len = %d, sec: %ld, usec: %ld\n",
|
|
||||||
(skb->len-ETH_HLEN), tv.tv_sec, tv.tv_usec);
|
|
||||||
|
|
||||||
#ifdef BCM_SHM_INTERFACE
|
|
||||||
spin_lock(&Adapter->txtransmitlock);
|
|
||||||
if(Adapter->txtransmit_running == 0)
|
|
||||||
{
|
|
||||||
Adapter->txtransmit_running = 1;
|
|
||||||
calltransmit = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
calltransmit = 0;
|
|
||||||
|
|
||||||
spin_unlock(&Adapter->txtransmitlock);
|
|
||||||
#endif
|
|
||||||
if(calltransmit == 1)
|
|
||||||
transmit_packets(Adapter);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(!atomic_read(&Adapter->TxPktAvail))
|
|
||||||
{
|
|
||||||
atomic_set(&Adapter->TxPktAvail, 1);
|
|
||||||
#ifdef BCM_SHM_INTERFACE
|
|
||||||
virtual_mail_box_interrupt();
|
|
||||||
#endif
|
|
||||||
wake_up(&Adapter->tx_packet_wait_queue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "<====");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
bcm_kfree_skb(skb);
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ingroup ctrl_pkt_functions
|
@ingroup ctrl_pkt_functions
|
||||||
This function dispatches control packet to the h/w interface
|
This function dispatches control packet to the h/w interface
|
||||||
@return zero(success) or -ve value(failure)
|
@return zero(success) or -ve value(failure)
|
||||||
*/
|
*/
|
||||||
INT SendControlPacket(PMINI_ADAPTER Adapter, /**<Logical Adapter*/
|
INT SendControlPacket(PMINI_ADAPTER Adapter, char *pControlPacket)
|
||||||
char *pControlPacket/**<Control Packet*/
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
PLEADER PLeader = NULL;
|
PLEADER PLeader = (PLEADER)pControlPacket;
|
||||||
struct timeval tv;
|
|
||||||
memset(&tv, 0, sizeof(tv));
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "========>");
|
|
||||||
|
|
||||||
PLeader=(PLEADER)pControlPacket;
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Tx");
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Tx");
|
||||||
if(!pControlPacket || !Adapter)
|
if(!pControlPacket || !Adapter)
|
||||||
{
|
{
|
||||||
@ -208,12 +55,6 @@ INT SendControlPacket(PMINI_ADAPTER Adapter, /**<Logical Adapter*/
|
|||||||
((PLeader->PLength-1)/MAX_DEVICE_DESC_SIZE)+1))
|
((PLeader->PLength-1)/MAX_DEVICE_DESC_SIZE)+1))
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "NO FREE DESCRIPTORS TO SEND CONTROL PACKET");
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "NO FREE DESCRIPTORS TO SEND CONTROL PACKET");
|
||||||
if(Adapter->bcm_jiffies == 0)
|
|
||||||
{
|
|
||||||
Adapter->bcm_jiffies = jiffies;
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "UPDATED TIME(hex): %lu",
|
|
||||||
Adapter->bcm_jiffies);
|
|
||||||
}
|
|
||||||
return STATUS_FAILURE;
|
return STATUS_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,76 +65,33 @@ INT SendControlPacket(PMINI_ADAPTER Adapter, /**<Logical Adapter*/
|
|||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader Length: %x",PLeader->PLength);
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader Length: %x",PLeader->PLength);
|
||||||
if(Adapter->device_removed)
|
if(Adapter->device_removed)
|
||||||
return 0;
|
return 0;
|
||||||
#ifndef BCM_SHM_INTERFACE
|
|
||||||
|
if (netif_msg_pktdata(Adapter))
|
||||||
|
print_hex_dump(KERN_DEBUG, PFX "tx control: ", DUMP_PREFIX_NONE,
|
||||||
|
16, 1, pControlPacket, PLeader->PLength + LEADER_SIZE, 0);
|
||||||
|
|
||||||
Adapter->interface_transmit(Adapter->pvInterfaceAdapter,
|
Adapter->interface_transmit(Adapter->pvInterfaceAdapter,
|
||||||
pControlPacket, (PLeader->PLength + LEADER_SIZE));
|
pControlPacket, (PLeader->PLength + LEADER_SIZE));
|
||||||
#else
|
|
||||||
tx_pkts_to_firmware(pControlPacket,(PLeader->PLength + LEADER_SIZE),1);
|
|
||||||
|
|
||||||
if(PLeader->Status==IDLE_MESSAGE)
|
|
||||||
{
|
|
||||||
if(((CONTROL_MESSAGE*)PLeader)->szData[0] == GO_TO_IDLE_MODE_PAYLOAD &&
|
|
||||||
((CONTROL_MESSAGE*)PLeader)->szData[1] == TARGET_CAN_GO_TO_IDLE_MODE)
|
|
||||||
{
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Idle Mode Ack Sent to the Device\n");
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Host Entering into Idle Mode\n");
|
|
||||||
do_gettimeofday(&tv);
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "IdleMode Msg sent to f/w at time :%ld ms", tv.tv_sec *1000 + tv.tv_usec /1000);
|
|
||||||
if(Adapter->bDoSuspend != TRUE)
|
|
||||||
{
|
|
||||||
Adapter->IdleMode = TRUE;
|
|
||||||
Adapter->bPreparingForLowPowerMode = FALSE ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if((PLeader->Status == LINK_UP_CONTROL_REQ) &&
|
|
||||||
((PUCHAR)pControlPacket)[sizeof(LEADER)] == LINK_UP_ACK &&
|
|
||||||
((PUCHAR)pControlPacket)[sizeof(LEADER)+1] ==
|
|
||||||
LINK_SHUTDOWN_REQ_FROM_FIRMWARE &&
|
|
||||||
((PUCHAR)pControlPacket)[sizeof(LEADER)+2] == SHUTDOWN_ACK_FROM_DRIVER)
|
|
||||||
{
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Shut Down ACK Sent and Host entering Shut State \n");
|
|
||||||
if(Adapter->bDoSuspend != TRUE)
|
|
||||||
{
|
|
||||||
Adapter->bShutStatus = TRUE;
|
|
||||||
Adapter->bPreparingForLowPowerMode = FALSE;
|
|
||||||
Adapter->bTriedToWakeUpFromlowPowerMode = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats.tx_packets++;
|
|
||||||
((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats.tx_bytes+=
|
|
||||||
PLeader->PLength;
|
|
||||||
atomic_dec(&Adapter->CurrNumFreeTxDesc);
|
atomic_dec(&Adapter->CurrNumFreeTxDesc);
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "<=========");
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "<=========");
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
static LEADER Leader={0};
|
|
||||||
/**
|
/**
|
||||||
@ingroup tx_functions
|
@ingroup tx_functions
|
||||||
This function despatches the IP packets with the given vcid
|
This function despatches the IP packets with the given vcid
|
||||||
to the target via the host h/w interface.
|
to the target via the host h/w interface.
|
||||||
@return zero(success) or -ve value(failure)
|
@return zero(success) or -ve value(failure)
|
||||||
*/
|
*/
|
||||||
INT SetupNextSend(PMINI_ADAPTER Adapter, /**<Logical Adapter*/
|
INT SetupNextSend(PMINI_ADAPTER Adapter, struct sk_buff *Packet, USHORT Vcid)
|
||||||
struct sk_buff *Packet, /**<data buffer*/
|
|
||||||
USHORT Vcid) /**<VCID for this packet*/
|
|
||||||
{
|
{
|
||||||
int status=0;
|
int status=0;
|
||||||
#ifdef GDMA_INTERFACE
|
|
||||||
int dontfree = 0;
|
|
||||||
#endif
|
|
||||||
BOOLEAN bHeaderSupressionEnabled = FALSE;
|
BOOLEAN bHeaderSupressionEnabled = FALSE;
|
||||||
B_UINT16 uiClassifierRuleID;
|
B_UINT16 uiClassifierRuleID;
|
||||||
int QueueIndex = NO_OF_QUEUES + 1;
|
u16 QueueIndex = skb_get_queue_mapping(Packet);
|
||||||
|
LEADER Leader={0};
|
||||||
|
|
||||||
if(!Adapter || !Packet)
|
|
||||||
{
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Got NULL Adapter or Packet");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
if(Packet->len > MAX_DEVICE_DESC_SIZE)
|
if(Packet->len > MAX_DEVICE_DESC_SIZE)
|
||||||
{
|
{
|
||||||
status = STATUS_FAILURE;
|
status = STATUS_FAILURE;
|
||||||
@ -302,14 +100,10 @@ INT SetupNextSend(PMINI_ADAPTER Adapter, /**<Logical Adapter*/
|
|||||||
|
|
||||||
/* Get the Classifier Rule ID */
|
/* Get the Classifier Rule ID */
|
||||||
uiClassifierRuleID = *((UINT32*) (Packet->cb)+SKB_CB_CLASSIFICATION_OFFSET);
|
uiClassifierRuleID = *((UINT32*) (Packet->cb)+SKB_CB_CLASSIFICATION_OFFSET);
|
||||||
QueueIndex = SearchVcid( Adapter,Vcid);
|
|
||||||
if(QueueIndex < NO_OF_QUEUES)
|
bHeaderSupressionEnabled = Adapter->PackInfo[QueueIndex].bHeaderSuppressionEnabled
|
||||||
{
|
& Adapter->bPHSEnabled;
|
||||||
bHeaderSupressionEnabled =
|
|
||||||
Adapter->PackInfo[QueueIndex].bHeaderSuppressionEnabled;
|
|
||||||
bHeaderSupressionEnabled =
|
|
||||||
bHeaderSupressionEnabled & Adapter->bPHSEnabled;
|
|
||||||
}
|
|
||||||
if(Adapter->device_removed)
|
if(Adapter->device_removed)
|
||||||
{
|
{
|
||||||
status = STATUS_FAILURE;
|
status = STATUS_FAILURE;
|
||||||
@ -327,15 +121,10 @@ INT SetupNextSend(PMINI_ADAPTER Adapter, /**<Logical Adapter*/
|
|||||||
|
|
||||||
Leader.Vcid = Vcid;
|
Leader.Vcid = Vcid;
|
||||||
|
|
||||||
if(TCP_ACK == *((UINT32*) (Packet->cb) + SKB_CB_TCPACK_OFFSET ))
|
if(TCP_ACK == *((UINT32*) (Packet->cb) + SKB_CB_TCPACK_OFFSET ))
|
||||||
{
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Sending TCP ACK\n");
|
|
||||||
Leader.Status = LEADER_STATUS_TCP_ACK;
|
Leader.Status = LEADER_STATUS_TCP_ACK;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
Leader.Status = LEADER_STATUS;
|
Leader.Status = LEADER_STATUS;
|
||||||
}
|
|
||||||
|
|
||||||
if(Adapter->PackInfo[QueueIndex].bEthCSSupport)
|
if(Adapter->PackInfo[QueueIndex].bEthCSSupport)
|
||||||
{
|
{
|
||||||
@ -351,68 +140,53 @@ INT SetupNextSend(PMINI_ADAPTER Adapter, /**<Logical Adapter*/
|
|||||||
skb_push(Packet, LEADER_SIZE);
|
skb_push(Packet, LEADER_SIZE);
|
||||||
memcpy(Packet->data, &Leader, LEADER_SIZE);
|
memcpy(Packet->data, &Leader, LEADER_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Leader.PLength = Packet->len - ETH_HLEN;
|
Leader.PLength = Packet->len - ETH_HLEN;
|
||||||
memcpy((LEADER*)skb_pull(Packet, (ETH_HLEN - LEADER_SIZE)), &Leader, LEADER_SIZE);
|
memcpy((LEADER*)skb_pull(Packet, (ETH_HLEN - LEADER_SIZE)), &Leader, LEADER_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Packet->len = %d", Packet->len);
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Vcid = %d", Vcid);
|
|
||||||
|
|
||||||
#ifndef BCM_SHM_INTERFACE
|
|
||||||
status = Adapter->interface_transmit(Adapter->pvInterfaceAdapter,
|
status = Adapter->interface_transmit(Adapter->pvInterfaceAdapter,
|
||||||
Packet->data, (Leader.PLength + LEADER_SIZE));
|
Packet->data, (Leader.PLength + LEADER_SIZE));
|
||||||
#else
|
|
||||||
status = tx_pkts_to_firmware(Packet,Packet->len,0);
|
|
||||||
#endif
|
|
||||||
if(status)
|
if(status)
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Tx Failed..\n");
|
++Adapter->dev->stats.tx_errors;
|
||||||
|
if (netif_msg_tx_err(Adapter))
|
||||||
|
pr_info(PFX "%s: transmit error %d\n", Adapter->dev->name,
|
||||||
|
status);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
struct netdev_queue *txq = netdev_get_tx_queue(Adapter->dev, QueueIndex);
|
||||||
Adapter->PackInfo[QueueIndex].uiTotalTxBytes += Leader.PLength;
|
Adapter->PackInfo[QueueIndex].uiTotalTxBytes += Leader.PLength;
|
||||||
atomic_add(Leader.PLength, &Adapter->GoodTxByteCount);
|
|
||||||
atomic_inc(&Adapter->TxTotalPacketCount);
|
|
||||||
#ifdef GDMA_INTERFACE
|
|
||||||
dontfree = 1;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
atomic_dec(&Adapter->CurrNumFreeTxDesc);
|
txq->tx_bytes += Leader.PLength;
|
||||||
|
++txq->tx_packets;
|
||||||
|
|
||||||
errExit:
|
|
||||||
|
|
||||||
if(STATUS_SUCCESS == status)
|
|
||||||
{
|
|
||||||
Adapter->PackInfo[QueueIndex].uiCurrentTokenCount -= Leader.PLength << 3;
|
Adapter->PackInfo[QueueIndex].uiCurrentTokenCount -= Leader.PLength << 3;
|
||||||
Adapter->PackInfo[QueueIndex].uiSentBytes += (Packet->len);
|
Adapter->PackInfo[QueueIndex].uiSentBytes += (Packet->len);
|
||||||
Adapter->PackInfo[QueueIndex].uiSentPackets++;
|
Adapter->PackInfo[QueueIndex].uiSentPackets++;
|
||||||
Adapter->PackInfo[QueueIndex].NumOfPacketsSent++;
|
Adapter->PackInfo[QueueIndex].NumOfPacketsSent++;
|
||||||
|
|
||||||
atomic_dec(&Adapter->PackInfo[QueueIndex].uiPerSFTxResourceCount);
|
atomic_dec(&Adapter->PackInfo[QueueIndex].uiPerSFTxResourceCount);
|
||||||
#ifdef BCM_SHM_INTERFACE
|
|
||||||
if(atomic_read(&Adapter->PackInfo[QueueIndex].uiPerSFTxResourceCount) < 0)
|
|
||||||
{
|
|
||||||
atomic_set(&Adapter->PackInfo[QueueIndex].uiPerSFTxResourceCount, 0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
Adapter->PackInfo[QueueIndex].uiThisPeriodSentBytes += Leader.PLength;
|
Adapter->PackInfo[QueueIndex].uiThisPeriodSentBytes += Leader.PLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
atomic_dec(&Adapter->CurrNumFreeTxDesc);
|
||||||
|
|
||||||
#ifdef GDMA_INTERFACE
|
errExit:
|
||||||
if(!dontfree){
|
|
||||||
bcm_kfree_skb(Packet);
|
dev_kfree_skb(Packet);
|
||||||
}
|
|
||||||
#else
|
|
||||||
bcm_kfree_skb(Packet);
|
|
||||||
#endif
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int tx_pending(PMINI_ADAPTER Adapter)
|
||||||
|
{
|
||||||
|
return (atomic_read(&Adapter->TxPktAvail)
|
||||||
|
&& MINIMUM_PENDING_DESCRIPTORS < atomic_read(&Adapter->CurrNumFreeTxDesc))
|
||||||
|
|| Adapter->device_removed || (1 == Adapter->downloadDDR);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ingroup tx_functions
|
@ingroup tx_functions
|
||||||
Transmit thread
|
Transmit thread
|
||||||
@ -420,57 +194,26 @@ Transmit thread
|
|||||||
int tx_pkt_handler(PMINI_ADAPTER Adapter /**< pointer to adapter object*/
|
int tx_pkt_handler(PMINI_ADAPTER Adapter /**< pointer to adapter object*/
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
#ifndef BCM_SHM_INTERFACE
|
|
||||||
int status = 0;
|
int status = 0;
|
||||||
#endif
|
|
||||||
|
|
||||||
UINT calltransmit = 1;
|
while(! kthread_should_stop()) {
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Entring to wait for signal from the interrupt service thread!Adapter = %p",Adapter);
|
/* FIXME - the timeout looks like workaround for racey usage of TxPktAvail */
|
||||||
|
if(Adapter->LinkUpStatus)
|
||||||
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
if(Adapter->LinkUpStatus){
|
|
||||||
wait_event_timeout(Adapter->tx_packet_wait_queue,
|
wait_event_timeout(Adapter->tx_packet_wait_queue,
|
||||||
((atomic_read(&Adapter->TxPktAvail) &&
|
tx_pending(Adapter), msecs_to_jiffies(10));
|
||||||
(MINIMUM_PENDING_DESCRIPTORS <
|
else
|
||||||
atomic_read(&Adapter->CurrNumFreeTxDesc)) &&
|
wait_event_interruptible(Adapter->tx_packet_wait_queue,
|
||||||
(Adapter->device_removed == FALSE))) ||
|
tx_pending(Adapter));
|
||||||
(1 == Adapter->downloadDDR) || kthread_should_stop()
|
|
||||||
#ifndef BCM_SHM_INTERFACE
|
|
||||||
|| (TRUE == Adapter->bEndPointHalted)
|
|
||||||
#endif
|
|
||||||
, msecs_to_jiffies(10));
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
wait_event(Adapter->tx_packet_wait_queue,
|
|
||||||
((atomic_read(&Adapter->TxPktAvail) &&
|
|
||||||
(MINIMUM_PENDING_DESCRIPTORS <
|
|
||||||
atomic_read(&Adapter->CurrNumFreeTxDesc)) &&
|
|
||||||
(Adapter->device_removed == FALSE))) ||
|
|
||||||
(1 == Adapter->downloadDDR) || kthread_should_stop()
|
|
||||||
#ifndef BCM_SHM_INTERFACE
|
|
||||||
|| (TRUE == Adapter->bEndPointHalted)
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(kthread_should_stop() || Adapter->device_removed)
|
if (Adapter->device_removed)
|
||||||
{
|
break;
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Exiting the tx thread..\n");
|
|
||||||
Adapter->transmit_packet_thread = NULL;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef BCM_SHM_INTERFACE
|
|
||||||
|
|
||||||
if(Adapter->downloadDDR == 1)
|
if(Adapter->downloadDDR == 1)
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Downloading DDR Settings\n");
|
|
||||||
Adapter->downloadDDR +=1;
|
Adapter->downloadDDR +=1;
|
||||||
status = download_ddr_settings(Adapter);
|
status = download_ddr_settings(Adapter);
|
||||||
if(status)
|
if(status)
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "DDR DOWNLOAD FAILED!\n");
|
pr_err(PFX "DDR DOWNLOAD FAILED! %d\n", status);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -489,7 +232,6 @@ int tx_pkt_handler(PMINI_ADAPTER Adapter /**< pointer to adapter object*/
|
|||||||
update_per_sf_desc_cnts(Adapter);
|
update_per_sf_desc_cnts(Adapter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if( atomic_read(&Adapter->CurrNumFreeTxDesc) &&
|
if( atomic_read(&Adapter->CurrNumFreeTxDesc) &&
|
||||||
Adapter->LinkStatus == SYNC_UP_REQUEST &&
|
Adapter->LinkStatus == SYNC_UP_REQUEST &&
|
||||||
@ -507,49 +249,12 @@ int tx_pkt_handler(PMINI_ADAPTER Adapter /**< pointer to adapter object*/
|
|||||||
wake_up(&Adapter->process_rx_cntrlpkt);
|
wake_up(&Adapter->process_rx_cntrlpkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BCM_SHM_INTERFACE
|
transmit_packets(Adapter);
|
||||||
spin_lock_bh(&Adapter->txtransmitlock);
|
|
||||||
if(Adapter->txtransmit_running == 0)
|
|
||||||
{
|
|
||||||
Adapter->txtransmit_running = 1;
|
|
||||||
calltransmit = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
calltransmit = 0;
|
|
||||||
spin_unlock_bh(&Adapter->txtransmitlock);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(calltransmit)
|
|
||||||
transmit_packets(Adapter);
|
|
||||||
|
|
||||||
atomic_set(&Adapter->TxPktAvail, 0);
|
atomic_set(&Adapter->TxPktAvail, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Exiting the tx thread..\n");
|
||||||
|
Adapter->transmit_packet_thread = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BCM_SHM_INTERFACE
|
|
||||||
extern PMINI_ADAPTER psAdaptertest;
|
|
||||||
void virtual_mail_box_interrupt(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
#ifndef GDMA_INTERFACE
|
|
||||||
PUINT ptr = (PUINT)CPE_VIRTUAL_MAILBOX_REG;
|
|
||||||
UINT intval = (UINT)((*ptr & 0xFF00) >> 8);
|
|
||||||
if (intval != 0)
|
|
||||||
{
|
|
||||||
atomic_set(&psAdaptertest->CurrNumFreeTxDesc, intval);
|
|
||||||
atomic_set (&psAdaptertest->uiMBupdate, TRUE);
|
|
||||||
|
|
||||||
//make it to 0
|
|
||||||
*ptr = *ptr & 0xffff00ff;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
unsigned int total_tx_pkts_pending(void)
|
|
||||||
{
|
|
||||||
return atomic_read(&psAdaptertest->TotalPacketCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,19 +2,6 @@
|
|||||||
#define CNTRL_SIGNALING_INTERFACE_
|
#define CNTRL_SIGNALING_INTERFACE_
|
||||||
|
|
||||||
|
|
||||||
#ifdef BECEEM_TARGET
|
|
||||||
|
|
||||||
#include <mac_common.h>
|
|
||||||
#include <msg_Dsa.h>
|
|
||||||
#include <msg_Dsc.h>
|
|
||||||
#include <msg_Dsd.h>
|
|
||||||
#include <sch_definitions.h>
|
|
||||||
using namespace Beceem;
|
|
||||||
#ifdef ENABLE_CORRIGENDUM2_UPDATE
|
|
||||||
extern B_UINT32 g_u32Corr2MacFlags;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
|
|
||||||
#define DSA_REQ 11
|
#define DSA_REQ 11
|
||||||
@ -28,7 +15,6 @@ extern B_UINT32 g_u32Corr2MacFlags;
|
|||||||
#define DSD_ACK 19
|
#define DSD_ACK 19
|
||||||
#define MAX_CLASSIFIERS_IN_SF 4
|
#define MAX_CLASSIFIERS_IN_SF 4
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MAX_STRING_LEN 20
|
#define MAX_STRING_LEN 20
|
||||||
#define MAX_PHS_LENGTHS 255
|
#define MAX_PHS_LENGTHS 255
|
||||||
@ -57,37 +43,7 @@ extern B_UINT32 g_u32Corr2MacFlags;
|
|||||||
////////////////////////structure Definitions///////////////////////////////////
|
////////////////////////structure Definitions///////////////////////////////////
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// \brief class cCPacketClassificationRule
|
/// \brief class cCPacketClassificationRule
|
||||||
#ifdef BECEEM_TARGET
|
|
||||||
class CCPacketClassificationRuleSI{
|
|
||||||
public:
|
|
||||||
/// \brief Constructor for the class
|
|
||||||
CCPacketClassificationRuleSI():
|
|
||||||
u8ClassifierRulePriority(mClassifierRulePriority),
|
|
||||||
u8IPTypeOfServiceLength(mIPTypeOfService),
|
|
||||||
u8Protocol(mProtocol),
|
|
||||||
u8IPMaskedSourceAddressLength(0),
|
|
||||||
u8IPDestinationAddressLength(0),
|
|
||||||
u8ProtocolSourcePortRangeLength(0),
|
|
||||||
u8ProtocolDestPortRangeLength(0),
|
|
||||||
u8EthernetDestMacAddressLength(0),
|
|
||||||
u8EthernetSourceMACAddressLength(0),
|
|
||||||
u8EthertypeLength(0),
|
|
||||||
u16UserPriority(mUserPriority),
|
|
||||||
u16VLANID(mVLANID),
|
|
||||||
u8AssociatedPHSI(mAssociatedPHSI),
|
|
||||||
u16PacketClassificationRuleIndex(mPacketClassifierRuleIndex),
|
|
||||||
u8VendorSpecificClassifierParamLength(mVendorSpecificClassifierParamLength),
|
|
||||||
u8IPv6FlowLableLength(mIPv6FlowLableLength),
|
|
||||||
u8ClassifierActionRule(mClassifierActionRule)
|
|
||||||
|
|
||||||
{}
|
|
||||||
void Reset()
|
|
||||||
{
|
|
||||||
CCPacketClassificationRuleSI();
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
struct _stCPacketClassificationRuleSI{
|
struct _stCPacketClassificationRuleSI{
|
||||||
#endif
|
|
||||||
|
|
||||||
/** 16bit UserPriority Of The Service Flow*/
|
/** 16bit UserPriority Of The Service Flow*/
|
||||||
B_UINT16 u16UserPriority;
|
B_UINT16 u16UserPriority;
|
||||||
@ -145,29 +101,10 @@ struct _stCPacketClassificationRuleSI{
|
|||||||
B_UINT8 u8ClassifierActionRule;
|
B_UINT8 u8ClassifierActionRule;
|
||||||
B_UINT16 u16ValidityBitMap;
|
B_UINT16 u16ValidityBitMap;
|
||||||
};
|
};
|
||||||
#ifndef BECEEM_TARGET
|
|
||||||
typedef struct _stCPacketClassificationRuleSI CCPacketClassificationRuleSI,stCPacketClassificationRuleSI, *pstCPacketClassificationRuleSI;
|
typedef struct _stCPacketClassificationRuleSI CCPacketClassificationRuleSI,stCPacketClassificationRuleSI, *pstCPacketClassificationRuleSI;
|
||||||
#endif
|
|
||||||
|
|
||||||
/// \brief class CPhsRuleSI
|
/// \brief class CPhsRuleSI
|
||||||
#ifdef BECEEM_TARGET
|
|
||||||
class CPhsRuleSI{
|
|
||||||
public:
|
|
||||||
/// \brief Constructor for the class
|
|
||||||
CPhsRuleSI():
|
|
||||||
u8PHSI(mPHSI),
|
|
||||||
u8PHSFLength(0),
|
|
||||||
u8PHSMLength(0),
|
|
||||||
u8PHSS(mPHSS),
|
|
||||||
u8PHSV(mPHSV),
|
|
||||||
u8VendorSpecificPHSParamsLength(mVendorSpecificPHSParamLength){}
|
|
||||||
void Reset()
|
|
||||||
{
|
|
||||||
CPhsRuleSI();
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
typedef struct _stPhsRuleSI {
|
typedef struct _stPhsRuleSI {
|
||||||
#endif
|
|
||||||
/** 8bit PHS Index Of The Service Flow*/
|
/** 8bit PHS Index Of The Service Flow*/
|
||||||
B_UINT8 u8PHSI;
|
B_UINT8 u8PHSI;
|
||||||
/** PHSF Length Of The Service Flow*/
|
/** PHSF Length Of The Service Flow*/
|
||||||
@ -188,31 +125,11 @@ typedef struct _stPhsRuleSI {
|
|||||||
B_UINT8 u8VendorSpecificPHSParams[VENDOR_PHS_PARAM_LENGTH];
|
B_UINT8 u8VendorSpecificPHSParams[VENDOR_PHS_PARAM_LENGTH];
|
||||||
|
|
||||||
B_UINT8 u8Padding[2];
|
B_UINT8 u8Padding[2];
|
||||||
#ifdef BECEEM_TARGET
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
}stPhsRuleSI,*pstPhsRuleSI;
|
}stPhsRuleSI,*pstPhsRuleSI;
|
||||||
typedef stPhsRuleSI CPhsRuleSI;
|
typedef stPhsRuleSI CPhsRuleSI;
|
||||||
#endif
|
|
||||||
|
|
||||||
/// \brief structure cConvergenceSLTypes
|
/// \brief structure cConvergenceSLTypes
|
||||||
#ifdef BECEEM_TARGET
|
|
||||||
class CConvergenceSLTypes{
|
|
||||||
public:
|
|
||||||
/// \brief Constructor for the class
|
|
||||||
CConvergenceSLTypes():
|
|
||||||
u8ClassfierDSCAction(mClassifierDSCAction),
|
|
||||||
u8PhsDSCAction (mPhsDSCAction)
|
|
||||||
{}
|
|
||||||
void Reset()
|
|
||||||
{
|
|
||||||
CConvergenceSLTypes();
|
|
||||||
cCPacketClassificationRule.Reset();
|
|
||||||
cPhsRule.Reset();
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
struct _stConvergenceSLTypes{
|
struct _stConvergenceSLTypes{
|
||||||
#endif
|
|
||||||
/** 8bit Phs Classfier Action Of The Service Flow*/
|
/** 8bit Phs Classfier Action Of The Service Flow*/
|
||||||
B_UINT8 u8ClassfierDSCAction;
|
B_UINT8 u8ClassfierDSCAction;
|
||||||
/** 8bit Phs DSC Action Of The Service Flow*/
|
/** 8bit Phs DSC Action Of The Service Flow*/
|
||||||
@ -220,111 +137,15 @@ struct _stConvergenceSLTypes{
|
|||||||
/** 16bit Padding */
|
/** 16bit Padding */
|
||||||
B_UINT8 u8Padding[2];
|
B_UINT8 u8Padding[2];
|
||||||
/// \brief class cCPacketClassificationRule
|
/// \brief class cCPacketClassificationRule
|
||||||
#ifdef BECEEM_TARGET
|
|
||||||
CCPacketClassificationRuleSI cCPacketClassificationRule;
|
|
||||||
#else
|
|
||||||
stCPacketClassificationRuleSI cCPacketClassificationRule;
|
stCPacketClassificationRuleSI cCPacketClassificationRule;
|
||||||
#endif
|
|
||||||
/// \brief class CPhsRuleSI
|
/// \brief class CPhsRuleSI
|
||||||
#ifdef BECEEM_TARGET
|
|
||||||
CPhsRuleSI cPhsRule;
|
|
||||||
#else
|
|
||||||
struct _stPhsRuleSI cPhsRule;
|
struct _stPhsRuleSI cPhsRule;
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
#ifndef BECEEM_TARGET
|
|
||||||
typedef struct _stConvergenceSLTypes stConvergenceSLTypes,CConvergenceSLTypes, *pstConvergenceSLTypes;
|
typedef struct _stConvergenceSLTypes stConvergenceSLTypes,CConvergenceSLTypes, *pstConvergenceSLTypes;
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/// \brief structure CServiceFlowParamSI
|
/// \brief structure CServiceFlowParamSI
|
||||||
#ifdef BECEEM_TARGET
|
|
||||||
class CServiceFlowParamSI{
|
|
||||||
public:
|
|
||||||
/// \brief Constructor for the class
|
|
||||||
CServiceFlowParamSI():
|
|
||||||
u32SFID(mSFid),
|
|
||||||
u16CID(mCid),
|
|
||||||
u8ServiceClassNameLength(mServiceClassNameLength),
|
|
||||||
u8MBSService(mMBSService),
|
|
||||||
u8QosParamSet(mQosParamSetType),
|
|
||||||
u8TrafficPriority(mTrafficPriority),
|
|
||||||
u32MaxSustainedTrafficRate(mMaximumSustainedTrafficRate),
|
|
||||||
u32MaxTrafficBurst(mMaximumTrafficBurst),
|
|
||||||
u32MinReservedTrafficRate(mMinimumReservedTrafficRate),
|
|
||||||
u8ServiceFlowSchedulingType(mServiceFlowSchedulingType),
|
|
||||||
u8RequesttransmissionPolicy(mRequestTransmissionPolicy),
|
|
||||||
u32ToleratedJitter(mToleratedJitter),
|
|
||||||
u32MaximumLatency(mMaximumLatency),
|
|
||||||
u8FixedLengthVSVariableLengthSDUIndicator
|
|
||||||
(mFixedLengthVSVariableLength),
|
|
||||||
u8SDUSize(mSDUSize),
|
|
||||||
u16TargetSAID(mTargetSAID),
|
|
||||||
u8ARQEnable(mARQEnable),
|
|
||||||
u16ARQWindowSize(mARQWindowSize),
|
|
||||||
u16ARQBlockLifeTime(mARQBlockLifeTime),
|
|
||||||
u16ARQSyncLossTimeOut(mARQSyncLossTimeOut),
|
|
||||||
u8ARQDeliverInOrder(mARQDeliverInOrder),
|
|
||||||
u16ARQRxPurgeTimeOut(mARQRXPurgeTimeOut),
|
|
||||||
//Add ARQ BLOCK SIZE, ARQ TX and RX delay initializations here
|
|
||||||
//after we move to only CORR2
|
|
||||||
u8RxARQAckProcessingTime(mRxARQAckProcessingTime),
|
|
||||||
u8CSSpecification(mCSSpecification),
|
|
||||||
u8TypeOfDataDeliveryService(mTypeOfDataDeliveryService),
|
|
||||||
u16SDUInterArrivalTime(mSDUInterArrivalTime),
|
|
||||||
u16TimeBase(mTimeBase),
|
|
||||||
u8PagingPreference(mPagingPreference),
|
|
||||||
u8MBSZoneIdentifierassignment(mMBSZoneIdentifierassignmentLength),
|
|
||||||
u8TrafficIndicationPreference(mTrafficIndicationPreference),
|
|
||||||
u8GlobalServicesClassNameLength(mGlobalServicesClassNameLength),
|
|
||||||
u8SNFeedbackEnabled(mSNFeedbackEnabled),
|
|
||||||
u8FSNSize(mFSNSize),
|
|
||||||
u8CIDAllocation4activeBSsLength(mCIDAllocation4activeBSsLength),
|
|
||||||
u16UnsolicitedGrantInterval(mUnsolicitedGrantInterval),
|
|
||||||
u16UnsolicitedPollingInterval(mUnsolicitedPollingInterval),
|
|
||||||
u8PDUSNExtendedSubheader4HarqReordering(mPDUSNExtendedSubheader4HarqReordering),
|
|
||||||
u8MBSContentsIDLength(mMBSContentsIDLength),
|
|
||||||
u8HARQServiceFlows(mHARQServiceFlows),
|
|
||||||
u8AuthTokenLength(mAuthTokenLength),
|
|
||||||
u8HarqChannelMappingLength(mHarqChannelMappingLength),
|
|
||||||
u8VendorSpecificQoSParamLength(mVendorSpecificQoSParamLength),
|
|
||||||
bValid(FALSE),
|
|
||||||
u8TotalClassifiers()
|
|
||||||
{
|
|
||||||
//Remove the bolck after we move to Corr2 only code
|
|
||||||
#ifdef ENABLE_CORRIGENDUM2_UPDATE
|
|
||||||
if((g_u32Corr2MacFlags & CORR_2_DSX) || (g_u32Corr2MacFlags & CORR_2_ARQ))
|
|
||||||
{
|
|
||||||
/* IEEE Comment #627 / MTG Comment #426 */
|
|
||||||
u16ARQBlockSize = mARQBlockSize;
|
|
||||||
if(g_u32Corr2MacFlags & CORR_2_ARQ) {
|
|
||||||
u16ARQRetryTxTimeOut = mARQRetryTimeOutTxDelay;
|
|
||||||
if(g_u32VENDOR_TYPE == VENDOR_ALCATEL) {
|
|
||||||
u16ARQRetryRxTimeOut = mARQRetryTimeOutRxDelay_ALU;
|
|
||||||
} else {
|
|
||||||
u16ARQRetryRxTimeOut = mARQRetryTimeOutRxDelay;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
u16ARQRetryTxTimeOut = mARQRetryTimeOutTxDelayCorr1;
|
|
||||||
u16ARQRetryRxTimeOut = mARQRetryTimeOutRxDelayCorr1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
u16ARQBlockSize = mARQBlockSizeCorr1;
|
|
||||||
u16ARQRetryTxTimeOut = mARQRetryTimeOutTxDelayCorr1;
|
|
||||||
u16ARQRetryRxTimeOut = mARQRetryTimeOutRxDelayCorr1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ComputeMacOverhead(B_UINT8 u8SecOvrhead);
|
|
||||||
B_UINT16 GetMacOverhead() { return u16MacOverhead; }
|
|
||||||
#else
|
|
||||||
typedef struct _stServiceFlowParamSI{
|
typedef struct _stServiceFlowParamSI{
|
||||||
#endif //end of ifdef BECEEM_TARGET
|
|
||||||
|
|
||||||
/** 32bitSFID Of The Service Flow*/
|
/** 32bitSFID Of The Service Flow*/
|
||||||
B_UINT32 u32SFID;
|
B_UINT32 u32SFID;
|
||||||
@ -367,11 +188,6 @@ typedef struct _stServiceFlowParamSI{
|
|||||||
|
|
||||||
/** 16bit ARQ Purge timeout */
|
/** 16bit ARQ Purge timeout */
|
||||||
B_UINT16 u16ARQRxPurgeTimeOut;
|
B_UINT16 u16ARQRxPurgeTimeOut;
|
||||||
#if 0 //def ENABLE_CORRIGENDUM2_UPDATE
|
|
||||||
/* IEEE Comment #627 / MTG Comment #426 */
|
|
||||||
/// \brief Size of an ARQ block, changed from 2 bytes to 1
|
|
||||||
B_UINT8 u8ARQBlockSize;
|
|
||||||
#endif
|
|
||||||
//TODO::Remove this once we move to a new CORR2 driver
|
//TODO::Remove this once we move to a new CORR2 driver
|
||||||
/// \brief Size of an ARQ block
|
/// \brief Size of an ARQ block
|
||||||
B_UINT16 u16ARQBlockSize;
|
B_UINT16 u16ARQBlockSize;
|
||||||
@ -496,35 +312,18 @@ typedef struct _stServiceFlowParamSI{
|
|||||||
B_UINT8 bValid; /**< Validity flag */
|
B_UINT8 bValid; /**< Validity flag */
|
||||||
B_UINT8 u8Padding; /**< Padding byte*/
|
B_UINT8 u8Padding; /**< Padding byte*/
|
||||||
|
|
||||||
#ifdef BECEEM_TARGET
|
|
||||||
/**
|
|
||||||
Structure for Convergence SubLayer Types with a maximum of 4 classifiers
|
|
||||||
*/
|
|
||||||
CConvergenceSLTypes cConvergenceSLTypes[MAX_CLASSIFIERS_IN_SF];
|
|
||||||
#else
|
|
||||||
/**
|
/**
|
||||||
Structure for Convergence SubLayer Types with a maximum of 4 classifiers
|
Structure for Convergence SubLayer Types with a maximum of 4 classifiers
|
||||||
*/
|
*/
|
||||||
stConvergenceSLTypes cConvergenceSLTypes[MAX_CLASSIFIERS_IN_SF];
|
stConvergenceSLTypes cConvergenceSLTypes[MAX_CLASSIFIERS_IN_SF];
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef BECEEM_TARGET
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
} stServiceFlowParamSI, *pstServiceFlowParamSI;
|
} stServiceFlowParamSI, *pstServiceFlowParamSI;
|
||||||
typedef stServiceFlowParamSI CServiceFlowParamSI;
|
typedef stServiceFlowParamSI CServiceFlowParamSI;
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
structure stLocalSFAddRequest
|
structure stLocalSFAddRequest
|
||||||
*/
|
*/
|
||||||
typedef struct _stLocalSFAddRequest{
|
typedef struct _stLocalSFAddRequest{
|
||||||
#ifdef BECEEM_TARGET
|
|
||||||
_stLocalSFAddRequest( ) :
|
|
||||||
u8Type(0x00), eConnectionDir(0x00),
|
|
||||||
u16TID(0x0000), u16CID(0x0000), u16VCID(0x0000)
|
|
||||||
{}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
B_UINT8 u8Type; /**< Type*/
|
B_UINT8 u8Type; /**< Type*/
|
||||||
B_UINT8 eConnectionDir; /**< Connection direction*/
|
B_UINT8 eConnectionDir; /**< Connection direction*/
|
||||||
@ -535,19 +334,9 @@ typedef struct _stLocalSFAddRequest{
|
|||||||
/// \brief 16bitVCID
|
/// \brief 16bitVCID
|
||||||
B_UINT16 u16VCID; /**< 16bit VCID*/
|
B_UINT16 u16VCID; /**< 16bit VCID*/
|
||||||
/// \brief structure ParameterSet
|
/// \brief structure ParameterSet
|
||||||
#ifdef BECEEM_SIGNALLING_INTERFACE_API
|
|
||||||
CServiceFlowParamSI sfParameterSet;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef BECEEM_TARGET
|
|
||||||
CServiceFlowParamSI *psfParameterSet;
|
|
||||||
#else
|
|
||||||
stServiceFlowParamSI *psfParameterSet; /**< structure ParameterSet*/
|
stServiceFlowParamSI *psfParameterSet; /**< structure ParameterSet*/
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USING_VXWORKS
|
|
||||||
USE_DATA_MEMORY_MANAGER();
|
|
||||||
#endif
|
|
||||||
}stLocalSFAddRequest, *pstLocalSFAddRequest;
|
}stLocalSFAddRequest, *pstLocalSFAddRequest;
|
||||||
|
|
||||||
|
|
||||||
@ -555,12 +344,6 @@ typedef struct _stLocalSFAddRequest{
|
|||||||
structure stLocalSFAddIndication
|
structure stLocalSFAddIndication
|
||||||
*/
|
*/
|
||||||
typedef struct _stLocalSFAddIndication{
|
typedef struct _stLocalSFAddIndication{
|
||||||
#ifdef BECEEM_TARGET
|
|
||||||
_stLocalSFAddIndication( ) :
|
|
||||||
u8Type(0x00), eConnectionDir(0x00),
|
|
||||||
u16TID(0x0000), u16CID(0x0000), u16VCID(0x0000)
|
|
||||||
{}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
B_UINT8 u8Type; /**< Type*/
|
B_UINT8 u8Type; /**< Type*/
|
||||||
B_UINT8 eConnectionDir; /**< Connection Direction*/
|
B_UINT8 eConnectionDir; /**< Connection Direction*/
|
||||||
@ -571,37 +354,19 @@ typedef struct _stLocalSFAddIndication{
|
|||||||
/// \brief 16bitVCID
|
/// \brief 16bitVCID
|
||||||
B_UINT16 u16VCID; /**< 16bitVCID*/
|
B_UINT16 u16VCID; /**< 16bitVCID*/
|
||||||
|
|
||||||
#ifdef BECEEM_SIGNALLING_INTERFACE_API
|
|
||||||
CServiceFlowParamSI sfAuthorizedSet;
|
|
||||||
/// \brief structure AdmittedSet
|
|
||||||
CServiceFlowParamSI sfAdmittedSet;
|
|
||||||
/// \brief structure ActiveSet
|
|
||||||
CServiceFlowParamSI sfActiveSet;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// \brief structure AuthorizedSet
|
/// \brief structure AuthorizedSet
|
||||||
#ifdef BECEEM_TARGET
|
|
||||||
CServiceFlowParamSI *psfAuthorizedSet;
|
|
||||||
/// \brief structure AdmittedSet
|
|
||||||
CServiceFlowParamSI *psfAdmittedSet;
|
|
||||||
/// \brief structure ActiveSet
|
|
||||||
CServiceFlowParamSI *psfActiveSet;
|
|
||||||
#else
|
|
||||||
/// \brief structure AuthorizedSet
|
/// \brief structure AuthorizedSet
|
||||||
stServiceFlowParamSI *psfAuthorizedSet; /**< AuthorizedSet of type stServiceFlowParamSI*/
|
stServiceFlowParamSI *psfAuthorizedSet; /**< AuthorizedSet of type stServiceFlowParamSI*/
|
||||||
/// \brief structure AdmittedSet
|
/// \brief structure AdmittedSet
|
||||||
stServiceFlowParamSI *psfAdmittedSet; /**< AdmittedSet of type stServiceFlowParamSI*/
|
stServiceFlowParamSI *psfAdmittedSet; /**< AdmittedSet of type stServiceFlowParamSI*/
|
||||||
/// \brief structure ActiveSet
|
/// \brief structure ActiveSet
|
||||||
stServiceFlowParamSI *psfActiveSet; /**< sfActiveSet of type stServiceFlowParamSI*/
|
stServiceFlowParamSI *psfActiveSet; /**< sfActiveSet of type stServiceFlowParamSI*/
|
||||||
#endif
|
|
||||||
B_UINT8 u8CC; /**< Confirmation Code*/
|
B_UINT8 u8CC; /**< Confirmation Code*/
|
||||||
B_UINT8 u8Padd; /**< 8-bit Padding */
|
B_UINT8 u8Padd; /**< 8-bit Padding */
|
||||||
|
|
||||||
B_UINT16 u16Padd; /**< 16 bit Padding */
|
B_UINT16 u16Padd; /**< 16 bit Padding */
|
||||||
|
|
||||||
#ifdef USING_VXWORKS
|
|
||||||
USE_DATA_MEMORY_MANAGER();
|
|
||||||
#endif
|
|
||||||
}stLocalSFAddIndication;
|
}stLocalSFAddIndication;
|
||||||
|
|
||||||
|
|
||||||
@ -619,33 +384,17 @@ typedef struct _stLocalSFAddIndication stLocalSFChangeIndication, *pstLocalSFCha
|
|||||||
structure stLocalSFDeleteRequest
|
structure stLocalSFDeleteRequest
|
||||||
*/
|
*/
|
||||||
typedef struct _stLocalSFDeleteRequest{
|
typedef struct _stLocalSFDeleteRequest{
|
||||||
#ifdef BECEEM_TARGET
|
|
||||||
_stLocalSFDeleteRequest( ) :
|
|
||||||
u8Type(0x00), u8Padding(0x00),
|
|
||||||
u16TID(0x0000), u32SFID (0x00000000)
|
|
||||||
{}
|
|
||||||
#endif
|
|
||||||
B_UINT8 u8Type; /**< Type*/
|
B_UINT8 u8Type; /**< Type*/
|
||||||
B_UINT8 u8Padding; /**< Padding byte*/
|
B_UINT8 u8Padding; /**< Padding byte*/
|
||||||
B_UINT16 u16TID; /**< TID*/
|
B_UINT16 u16TID; /**< TID*/
|
||||||
/// \brief 32bitSFID
|
/// \brief 32bitSFID
|
||||||
B_UINT32 u32SFID; /**< SFID*/
|
B_UINT32 u32SFID; /**< SFID*/
|
||||||
#ifdef USING_VXWORKS
|
|
||||||
USE_DATA_MEMORY_MANAGER();
|
|
||||||
#endif
|
|
||||||
}stLocalSFDeleteRequest, *pstLocalSFDeleteRequest;
|
}stLocalSFDeleteRequest, *pstLocalSFDeleteRequest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
structure stLocalSFDeleteIndication
|
structure stLocalSFDeleteIndication
|
||||||
*/
|
*/
|
||||||
typedef struct stLocalSFDeleteIndication{
|
typedef struct stLocalSFDeleteIndication{
|
||||||
#ifdef BECEEM_TARGET
|
|
||||||
stLocalSFDeleteIndication( ) :
|
|
||||||
u8Type(0x00), u8Padding(0x00),
|
|
||||||
u16TID(0x0000), u16CID(0x0000),
|
|
||||||
u16VCID(0x0000),u32SFID (0x00000000)
|
|
||||||
{}
|
|
||||||
#endif
|
|
||||||
B_UINT8 u8Type; /**< Type */
|
B_UINT8 u8Type; /**< Type */
|
||||||
B_UINT8 u8Padding; /**< Padding */
|
B_UINT8 u8Padding; /**< Padding */
|
||||||
B_UINT16 u16TID; /**< TID */
|
B_UINT16 u16TID; /**< TID */
|
||||||
@ -658,9 +407,6 @@ typedef struct stLocalSFDeleteIndication{
|
|||||||
/// \brief 8bit Confirmation code
|
/// \brief 8bit Confirmation code
|
||||||
B_UINT8 u8ConfirmationCode; /**< Confirmation code */
|
B_UINT8 u8ConfirmationCode; /**< Confirmation code */
|
||||||
B_UINT8 u8Padding1[3]; /**< 3 byte Padding */
|
B_UINT8 u8Padding1[3]; /**< 3 byte Padding */
|
||||||
#ifdef USING_VXWORKS
|
|
||||||
USE_DATA_MEMORY_MANAGER();
|
|
||||||
#endif
|
|
||||||
}stLocalSFDeleteIndication;
|
}stLocalSFDeleteIndication;
|
||||||
|
|
||||||
typedef struct _stIM_SFHostNotify
|
typedef struct _stIM_SFHostNotify
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
#include <linux/etherdevice.h>
|
#include <linux/etherdevice.h>
|
||||||
#include <net/ip.h>
|
#include <net/ip.h>
|
||||||
#include <linux/wait.h>
|
#include <linux/wait.h>
|
||||||
#include <linux/notifier.h>
|
|
||||||
#include <linux/proc_fs.h>
|
#include <linux/proc_fs.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
|
|
||||||
@ -36,26 +35,10 @@
|
|||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
#include <linux/pagemap.h>
|
#include <linux/pagemap.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
|
||||||
#include <linux/kthread.h>
|
#include <linux/kthread.h>
|
||||||
#endif
|
|
||||||
#include <linux/tcp.h>
|
#include <linux/tcp.h>
|
||||||
#include <linux/udp.h>
|
#include <linux/udp.h>
|
||||||
#ifndef BCM_SHM_INTERFACE
|
|
||||||
#include <linux/usb.h>
|
#include <linux/usb.h>
|
||||||
#endif
|
|
||||||
#ifdef BECEEM_TARGET
|
|
||||||
|
|
||||||
#include <mac_common.h>
|
|
||||||
#include <msg_Dsa.h>
|
|
||||||
#include <msg_Dsc.h>
|
|
||||||
#include <msg_Dsd.h>
|
|
||||||
#include <sch_definitions.h>
|
|
||||||
using namespace Beceem;
|
|
||||||
#ifdef ENABLE_CORRIGENDUM2_UPDATE
|
|
||||||
extern B_UINT32 g_u32Corr2MacFlags;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "Typedefs.h"
|
#include "Typedefs.h"
|
||||||
#include "Version.h"
|
#include "Version.h"
|
||||||
@ -71,39 +54,28 @@ extern B_UINT32 g_u32Corr2MacFlags;
|
|||||||
#include "CmHost.h"
|
#include "CmHost.h"
|
||||||
#include "DDRInit.h"
|
#include "DDRInit.h"
|
||||||
#include "Debug.h"
|
#include "Debug.h"
|
||||||
#include "HostMibs.h"
|
|
||||||
#include "IPv6ProtocolHdr.h"
|
#include "IPv6ProtocolHdr.h"
|
||||||
#include "osal_misc.h"
|
|
||||||
#include "PHSModule.h"
|
#include "PHSModule.h"
|
||||||
#include "Protocol.h"
|
#include "Protocol.h"
|
||||||
#include "Prototypes.h"
|
#include "Prototypes.h"
|
||||||
#include "Queue.h"
|
#include "Queue.h"
|
||||||
#include "vendorspecificextn.h"
|
#include "vendorspecificextn.h"
|
||||||
|
|
||||||
#ifndef BCM_SHM_INTERFACE
|
|
||||||
|
|
||||||
#include "InterfaceMacros.h"
|
#include "InterfaceMacros.h"
|
||||||
#include "InterfaceAdapter.h"
|
#include "InterfaceAdapter.h"
|
||||||
#include "InterfaceIsr.h"
|
#include "InterfaceIsr.h"
|
||||||
#include "Interfacemain.h"
|
|
||||||
#include "InterfaceMisc.h"
|
#include "InterfaceMisc.h"
|
||||||
#include "InterfaceRx.h"
|
#include "InterfaceRx.h"
|
||||||
#include "InterfaceTx.h"
|
#include "InterfaceTx.h"
|
||||||
#endif
|
|
||||||
#include "InterfaceIdleMode.h"
|
#include "InterfaceIdleMode.h"
|
||||||
#include "InterfaceInit.h"
|
#include "InterfaceInit.h"
|
||||||
|
|
||||||
#ifdef BCM_SHM_INTERFACE
|
#define DRV_NAME "beceem"
|
||||||
#include <linux/cpe_config.h>
|
#define DEV_NAME "tarang"
|
||||||
|
#define DRV_DESCRIPTION "Beceem Communications Inc. WiMAX driver"
|
||||||
#ifdef GDMA_INTERFACE
|
#define DRV_COPYRIGHT "Copyright 2010. Beceem Communications Inc"
|
||||||
#include "GdmaInterface.h"
|
#define DRV_VERSION VER_FILEVERSION_STR
|
||||||
#include "symphony.h"
|
#define PFX DRV_NAME " "
|
||||||
#else
|
|
||||||
#include "virtual_interface.h"
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -10,12 +10,8 @@
|
|||||||
*/
|
*/
|
||||||
#include "headers.h"
|
#include "headers.h"
|
||||||
|
|
||||||
INT ProcessGetHostMibs(PMINI_ADAPTER Adapter,
|
INT ProcessGetHostMibs(PMINI_ADAPTER Adapter, S_MIBS_HOST_STATS_MIBS *pstHostMibs)
|
||||||
PVOID ioBuffer,
|
|
||||||
ULONG inputBufferLength)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
S_MIBS_HOST_STATS_MIBS *pstHostMibs = NULL;
|
|
||||||
S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
|
S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
|
||||||
S_PHS_RULE *pstPhsRule = NULL;
|
S_PHS_RULE *pstPhsRule = NULL;
|
||||||
S_CLASSIFIER_TABLE *pstClassifierTable = NULL;
|
S_CLASSIFIER_TABLE *pstClassifierTable = NULL;
|
||||||
@ -30,15 +26,6 @@ INT ProcessGetHostMibs(PMINI_ADAPTER Adapter,
|
|||||||
return STATUS_FAILURE;
|
return STATUS_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ioBuffer == NULL)
|
|
||||||
{
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
memset(ioBuffer,0,sizeof(S_MIBS_HOST_STATS_MIBS));
|
|
||||||
|
|
||||||
pstHostMibs = (S_MIBS_HOST_STATS_MIBS *)ioBuffer;
|
|
||||||
|
|
||||||
|
|
||||||
//Copy the classifier Table
|
//Copy the classifier Table
|
||||||
for(nClassifierIndex=0; nClassifierIndex < MAX_CLASSIFIERS;
|
for(nClassifierIndex=0; nClassifierIndex < MAX_CLASSIFIERS;
|
||||||
nClassifierIndex++)
|
nClassifierIndex++)
|
||||||
@ -54,7 +41,7 @@ INT ProcessGetHostMibs(PMINI_ADAPTER Adapter,
|
|||||||
{
|
{
|
||||||
if(Adapter->PackInfo[nSfIndex].bValid)
|
if(Adapter->PackInfo[nSfIndex].bValid)
|
||||||
{
|
{
|
||||||
OsalMemMove((PVOID)&pstHostMibs->astSFtable[nSfIndex],(PVOID)&Adapter->PackInfo[nSfIndex],sizeof(S_MIBS_SERVICEFLOW_TABLE));
|
memcpy((PVOID)&pstHostMibs->astSFtable[nSfIndex],(PVOID)&Adapter->PackInfo[nSfIndex],sizeof(S_MIBS_SERVICEFLOW_TABLE));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -83,7 +70,7 @@ INT ProcessGetHostMibs(PMINI_ADAPTER Adapter,
|
|||||||
|
|
||||||
pstHostMibs->astPhsRulesTable[nPhsTableIndex].ulSFID = Adapter->PackInfo[nSfIndex].ulSFID;
|
pstHostMibs->astPhsRulesTable[nPhsTableIndex].ulSFID = Adapter->PackInfo[nSfIndex].ulSFID;
|
||||||
|
|
||||||
OsalMemMove(&pstHostMibs->astPhsRulesTable[nPhsTableIndex].u8PHSI,
|
memcpy(&pstHostMibs->astPhsRulesTable[nPhsTableIndex].u8PHSI,
|
||||||
&pstPhsRule->u8PHSI,
|
&pstPhsRule->u8PHSI,
|
||||||
sizeof(S_PHS_RULE));
|
sizeof(S_PHS_RULE));
|
||||||
nPhsTableIndex++;
|
nPhsTableIndex++;
|
||||||
@ -95,12 +82,9 @@ INT ProcessGetHostMibs(PMINI_ADAPTER Adapter,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//copy other Host Statistics parameters
|
//copy other Host Statistics parameters
|
||||||
pstHostMibs->stHostInfo.GoodTransmits =
|
pstHostMibs->stHostInfo.GoodTransmits = Adapter->dev->stats.tx_packets;
|
||||||
atomic_read(&Adapter->TxTotalPacketCount);
|
pstHostMibs->stHostInfo.GoodReceives = Adapter->dev->stats.rx_packets;
|
||||||
pstHostMibs->stHostInfo.GoodReceives =
|
|
||||||
atomic_read(&Adapter->GoodRxPktCount);
|
|
||||||
pstHostMibs->stHostInfo.CurrNumFreeDesc =
|
pstHostMibs->stHostInfo.CurrNumFreeDesc =
|
||||||
atomic_read(&Adapter->CurrNumFreeTxDesc);
|
atomic_read(&Adapter->CurrNumFreeTxDesc);
|
||||||
pstHostMibs->stHostInfo.BEBucketSize = Adapter->BEBucketSize;
|
pstHostMibs->stHostInfo.BEBucketSize = Adapter->BEBucketSize;
|
||||||
@ -115,13 +99,10 @@ INT ProcessGetHostMibs(PMINI_ADAPTER Adapter,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
INT GetDroppedAppCntrlPktMibs(PVOID ioBuffer, PPER_TARANG_DATA pTarang)
|
VOID GetDroppedAppCntrlPktMibs(S_MIBS_HOST_STATS_MIBS *pstHostMibs, const PPER_TARANG_DATA pTarang)
|
||||||
{
|
{
|
||||||
S_MIBS_HOST_STATS_MIBS *pstHostMibs = (S_MIBS_HOST_STATS_MIBS *)ioBuffer;
|
memcpy(&(pstHostMibs->stDroppedAppCntrlMsgs),
|
||||||
|
&(pTarang->stDroppedAppCntrlMsgs),sizeof(S_MIBS_DROPPED_APP_CNTRL_MESSAGES));
|
||||||
memcpy((PVOID)&(pstHostMibs->stDroppedAppCntrlMsgs),(PVOID)&(pTarang->stDroppedAppCntrlMsgs),sizeof(S_MIBS_DROPPED_APP_CNTRL_MESSAGES));
|
|
||||||
|
|
||||||
return STATUS_SUCCESS ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -108,52 +108,16 @@ static INT LED_Proportional_Blink(PMINI_ADAPTER Adapter, UCHAR GPIO_Num_tx,
|
|||||||
ulong timeout = 0;
|
ulong timeout = 0;
|
||||||
|
|
||||||
/*Read initial value of packets sent/received */
|
/*Read initial value of packets sent/received */
|
||||||
Initial_num_of_packts_tx = atomic_read(&Adapter->TxTotalPacketCount);
|
Initial_num_of_packts_tx = Adapter->dev->stats.tx_packets;
|
||||||
Initial_num_of_packts_rx = atomic_read(&Adapter->GoodRxPktCount);
|
Initial_num_of_packts_rx = Adapter->dev->stats.rx_packets;
|
||||||
|
|
||||||
/*Scale the rate of transfer to no of blinks.*/
|
/*Scale the rate of transfer to no of blinks.*/
|
||||||
num_of_time_tx= ScaleRateofTransfer((ULONG)rate_of_transfer_tx);
|
num_of_time_tx= ScaleRateofTransfer((ULONG)rate_of_transfer_tx);
|
||||||
num_of_time_rx= ScaleRateofTransfer((ULONG)rate_of_transfer_rx);
|
num_of_time_rx= ScaleRateofTransfer((ULONG)rate_of_transfer_rx);
|
||||||
|
|
||||||
while((Adapter->device_removed == FALSE))
|
while((Adapter->device_removed == FALSE))
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
if(0 == num_of_time_tx && 0 == num_of_time_rx)
|
|
||||||
{
|
|
||||||
timeout = 1000;
|
|
||||||
Status = wait_event_interruptible_timeout(Adapter->LEDInfo.notify_led_event,
|
|
||||||
currdriverstate!= Adapter->DriverState || kthread_should_stop(),
|
|
||||||
msecs_to_jiffies (timeout));
|
|
||||||
if(kthread_should_stop())
|
|
||||||
{
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "Led thread got signal to exit..hence exiting");
|
|
||||||
Adapter->LEDInfo.led_thread_running= BCM_LED_THREAD_DISABLED;
|
|
||||||
return EVENT_SIGNALED;
|
|
||||||
}
|
|
||||||
if(Status)
|
|
||||||
return EVENT_SIGNALED;
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
timeout = 50;
|
timeout = 50;
|
||||||
#if 0
|
|
||||||
/*Turn on LED if Tx is high bandwidth*/
|
|
||||||
if(num_of_time_tx > MAX_NUM_OF_BLINKS)
|
|
||||||
{
|
|
||||||
TURN_ON_LED(1<<GPIO_Num_tx, uiTxLedIndex);
|
|
||||||
num_of_time_tx = 0;
|
|
||||||
bBlinkBothLED = FALSE;
|
|
||||||
num_of_time = num_of_time_rx;
|
|
||||||
}
|
|
||||||
/*Turn on LED if Rx is high bandwidth*/
|
|
||||||
if(num_of_time_rx > MAX_NUM_OF_BLINKS)
|
|
||||||
{
|
|
||||||
TURN_ON_LED(1<<GPIO_Num_rx, uiRxLedIndex);
|
|
||||||
num_of_time_rx = 0;
|
|
||||||
bBlinkBothLED = FALSE;
|
|
||||||
num_of_time = num_of_time_tx;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/*Blink Tx and Rx LED when both Tx and Rx is in normal bandwidth*/
|
/*Blink Tx and Rx LED when both Tx and Rx is in normal bandwidth*/
|
||||||
if(bBlinkBothLED)
|
if(bBlinkBothLED)
|
||||||
{
|
{
|
||||||
@ -249,9 +213,10 @@ static INT LED_Proportional_Blink(PMINI_ADAPTER Adapter, UCHAR GPIO_Num_tx,
|
|||||||
* Read the Tx & Rx packets transmission after 1 second and
|
* Read the Tx & Rx packets transmission after 1 second and
|
||||||
* calculate rate of transfer
|
* calculate rate of transfer
|
||||||
*/
|
*/
|
||||||
Final_num_of_packts_tx = atomic_read(&Adapter->TxTotalPacketCount);
|
Final_num_of_packts_tx = Adapter->dev->stats.tx_packets;
|
||||||
|
Final_num_of_packts_rx = Adapter->dev->stats.rx_packets;
|
||||||
|
|
||||||
rate_of_transfer_tx = Final_num_of_packts_tx - Initial_num_of_packts_tx;
|
rate_of_transfer_tx = Final_num_of_packts_tx - Initial_num_of_packts_tx;
|
||||||
Final_num_of_packts_rx = atomic_read(&Adapter->GoodRxPktCount);
|
|
||||||
rate_of_transfer_rx = Final_num_of_packts_rx - Initial_num_of_packts_rx;
|
rate_of_transfer_rx = Final_num_of_packts_rx - Initial_num_of_packts_rx;
|
||||||
|
|
||||||
/*Read initial value of packets sent/received */
|
/*Read initial value of packets sent/received */
|
||||||
@ -293,7 +258,7 @@ static INT ValidateDSDParamsChecksum(
|
|||||||
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread:ValidateDSDParamsChecksum: 0x%lx 0x%X",ulParamOffset, usParamLen);
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread:ValidateDSDParamsChecksum: 0x%lx 0x%X",ulParamOffset, usParamLen);
|
||||||
|
|
||||||
puBuffer = OsalMemAlloc(usParamLen,"!MEM");
|
puBuffer = kmalloc(usParamLen, GFP_KERNEL);
|
||||||
if(!puBuffer)
|
if(!puBuffer)
|
||||||
{
|
{
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: ValidateDSDParamsChecksum Allocation failed");
|
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: ValidateDSDParamsChecksum Allocation failed");
|
||||||
@ -341,10 +306,7 @@ static INT ValidateDSDParamsChecksum(
|
|||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
if(puBuffer)
|
kfree(puBuffer);
|
||||||
{
|
|
||||||
OsalMemFree(puBuffer, usParamLen);
|
|
||||||
}
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -497,12 +459,10 @@ static int ReadConfigFileStructure(PMINI_ADAPTER Adapter, BOOLEAN *bEnableThread
|
|||||||
{
|
{
|
||||||
int Status = STATUS_SUCCESS;
|
int Status = STATUS_SUCCESS;
|
||||||
UCHAR GPIO_Array[NUM_OF_LEDS+1]; /*Array to store GPIO numbers from EEPROM*/
|
UCHAR GPIO_Array[NUM_OF_LEDS+1]; /*Array to store GPIO numbers from EEPROM*/
|
||||||
#ifndef BCM_SHM_INTERFACE
|
|
||||||
UINT uiIndex = 0;
|
UINT uiIndex = 0;
|
||||||
UINT uiNum_of_LED_Type = 0;
|
UINT uiNum_of_LED_Type = 0;
|
||||||
PUCHAR puCFGData = NULL;
|
PUCHAR puCFGData = NULL;
|
||||||
UCHAR bData = 0;
|
UCHAR bData = 0;
|
||||||
#endif
|
|
||||||
memset(GPIO_Array, DISABLE_GPIO_NUM, NUM_OF_LEDS+1);
|
memset(GPIO_Array, DISABLE_GPIO_NUM, NUM_OF_LEDS+1);
|
||||||
|
|
||||||
if(!Adapter->pstargetparams || IS_ERR(Adapter->pstargetparams))
|
if(!Adapter->pstargetparams || IS_ERR(Adapter->pstargetparams))
|
||||||
@ -524,10 +484,6 @@ static int ReadConfigFileStructure(PMINI_ADAPTER Adapter, BOOLEAN *bEnableThread
|
|||||||
*bEnableThread = FALSE;
|
*bEnableThread = FALSE;
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
#ifdef BCM_SHM_INTERFACE
|
|
||||||
*bEnableThread = FALSE;
|
|
||||||
return Status ;
|
|
||||||
#else
|
|
||||||
/*
|
/*
|
||||||
* CONFIG file read successfully. Deallocate the memory of
|
* CONFIG file read successfully. Deallocate the memory of
|
||||||
* uiFileNameBufferSize
|
* uiFileNameBufferSize
|
||||||
@ -578,23 +534,7 @@ static int ReadConfigFileStructure(PMINI_ADAPTER Adapter, BOOLEAN *bEnableThread
|
|||||||
}
|
}
|
||||||
if(uiNum_of_LED_Type >= NUM_OF_LEDS)
|
if(uiNum_of_LED_Type >= NUM_OF_LEDS)
|
||||||
*bEnableThread = FALSE;
|
*bEnableThread = FALSE;
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
for(uiIndex=0; uiIndex<NUM_OF_LEDS; uiIndex++)
|
|
||||||
{
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LEDState[%d].LED_Type = %x\n", uiIndex,
|
|
||||||
Adapter->LEDInfo.LEDState[uiIndex].LED_Type);
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LEDState[%d].LED_On_State = %x\n", uiIndex,
|
|
||||||
Adapter->LEDInfo.LEDState[uiIndex].LED_On_State);
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LEDState[%d].LED_Blink_State = %x\n", uiIndex,
|
|
||||||
Adapter->LEDInfo.LEDState[uiIndex].LED_Blink_State);
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LEDState[%d].GPIO_Num = %x\n", uiIndex,
|
|
||||||
Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num);
|
|
||||||
}
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: Polarity = %d\n",
|
|
||||||
Adapter->LEDInfo.BitPolarty);
|
|
||||||
#endif
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
@ -721,20 +661,6 @@ static VOID LEDControlThread(PMINI_ADAPTER Adapter)
|
|||||||
TURN_OFF_LED(1<<GPIO_num, uiLedIndex);
|
TURN_OFF_LED(1<<GPIO_num, uiLedIndex);
|
||||||
return ;//STATUS_FAILURE;
|
return ;//STATUS_FAILURE;
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
if(Adapter->device_removed)
|
|
||||||
{
|
|
||||||
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"Device removed hence exiting from Led Thread..");
|
|
||||||
return ; //-ENODEV;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#if 0
|
|
||||||
if((GPIO_num != DISABLE_GPIO_NUM) &&
|
|
||||||
((currdriverstate != FW_DOWNLOAD) &&
|
|
||||||
(currdriverstate != NORMAL_OPERATION) &&
|
|
||||||
(currdriverstate != IDLEMODE_EXIT)))
|
|
||||||
TURN_OFF_LED(1<<GPIO_num, uiLedIndex);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(GPIO_num != DISABLE_GPIO_NUM)
|
if(GPIO_num != DISABLE_GPIO_NUM)
|
||||||
{
|
{
|
||||||
@ -752,10 +678,6 @@ static VOID LEDControlThread(PMINI_ADAPTER Adapter)
|
|||||||
case DRIVER_INIT:
|
case DRIVER_INIT:
|
||||||
{
|
{
|
||||||
currdriverstate = DRIVER_INIT;//Adapter->DriverState;
|
currdriverstate = DRIVER_INIT;//Adapter->DriverState;
|
||||||
#if 0
|
|
||||||
LedGpioInit(Adapter);
|
|
||||||
Adapter->LEDInfo.bLedInitDone = TRUE;
|
|
||||||
#endif
|
|
||||||
BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum, &uiLedIndex, &dummyIndex, currdriverstate);
|
BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum, &uiLedIndex, &dummyIndex, currdriverstate);
|
||||||
|
|
||||||
if(GPIO_num != DISABLE_GPIO_NUM)
|
if(GPIO_num != DISABLE_GPIO_NUM)
|
||||||
@ -768,13 +690,6 @@ static VOID LEDControlThread(PMINI_ADAPTER Adapter)
|
|||||||
{
|
{
|
||||||
//BCM_DEBUG_PRINT (Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: FW_DN_DONE called\n");
|
//BCM_DEBUG_PRINT (Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: FW_DN_DONE called\n");
|
||||||
currdriverstate = FW_DOWNLOAD;
|
currdriverstate = FW_DOWNLOAD;
|
||||||
#if 0
|
|
||||||
if(Adapter->LEDInfo.bLedInitDone == FALSE)
|
|
||||||
{
|
|
||||||
LedGpioInit(Adapter);
|
|
||||||
Adapter->LEDInfo.bLedInitDone = TRUE;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum, &uiLedIndex, &dummyIndex, currdriverstate);
|
BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum, &uiLedIndex, &dummyIndex, currdriverstate);
|
||||||
|
|
||||||
if(GPIO_num != DISABLE_GPIO_NUM)
|
if(GPIO_num != DISABLE_GPIO_NUM)
|
||||||
@ -796,12 +711,6 @@ static VOID LEDControlThread(PMINI_ADAPTER Adapter)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SHUTDOWN_EXIT:
|
case SHUTDOWN_EXIT:
|
||||||
#if 0
|
|
||||||
if(Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_PMU_SHUTDOWN)
|
|
||||||
{
|
|
||||||
LedGpioInit(Adapter);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
//no break, continue to NO_NETWORK_ENTRY state as well.
|
//no break, continue to NO_NETWORK_ENTRY state as well.
|
||||||
|
|
||||||
case NO_NETWORK_ENTRY:
|
case NO_NETWORK_ENTRY:
|
||||||
@ -875,34 +784,6 @@ static VOID LEDControlThread(PMINI_ADAPTER Adapter)
|
|||||||
break;
|
break;
|
||||||
case IDLEMODE_EXIT:
|
case IDLEMODE_EXIT:
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
UCHAR GPIO_num_tx = DISABLE_GPIO_NUM;
|
|
||||||
UCHAR GPIO_num_rx = DISABLE_GPIO_NUM;
|
|
||||||
UCHAR uiTxLedIndex = 0;
|
|
||||||
UCHAR uiRxLedIndex = 0;
|
|
||||||
|
|
||||||
currdriverstate = IDLEMODE_EXIT;
|
|
||||||
if(DEVICE_POWERSAVE_MODE_AS_PMU_SHUTDOWN == Adapter->ulPowerSaveMode)
|
|
||||||
{
|
|
||||||
LedGpioInit(Adapter);
|
|
||||||
}
|
|
||||||
BcmGetGPIOPinInfo(Adapter, &GPIO_num_tx, &GPIO_num_rx, &uiTxLedIndex,&uiRxLedIndex,currdriverstate);
|
|
||||||
|
|
||||||
Adapter->LEDInfo.bIdle_led_off = FALSE;
|
|
||||||
|
|
||||||
if((GPIO_num_tx == DISABLE_GPIO_NUM) && (GPIO_num_rx == DISABLE_GPIO_NUM))
|
|
||||||
{
|
|
||||||
GPIO_num = DISABLE_GPIO_NUM ;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
timeout = 50;
|
|
||||||
if(Adapter->LEDInfo.bIdleMode_tx_from_host)
|
|
||||||
LED_Blink(Adapter, 1<<GPIO_num_tx, uiTxLedIndex, timeout, -1,currdriverstate);
|
|
||||||
else
|
|
||||||
LED_Blink(Adapter, 1<<GPIO_num_rx, uiRxLedIndex, timeout, -1,currdriverstate);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DRIVER_HALT:
|
case DRIVER_HALT:
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -323,15 +323,6 @@ typedef struct _ISO_HEADER
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef BCM_SHM_INTERFACE
|
|
||||||
|
|
||||||
#define FLASH_ADDR_MASK 0x1F000000
|
|
||||||
extern int bcmflash_raw_read(unsigned int flash_id, unsigned int offset, unsigned char *inbuf, unsigned int len);
|
|
||||||
extern int bcmflash_raw_write(unsigned int flash_id, unsigned int offset, unsigned char *outbuf, unsigned int len);
|
|
||||||
extern int bcmflash_raw_writenoerase(unsigned int flash_id, unsigned int offset, unsigned char *outbuf, unsigned int len);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define FLASH_CONTIGIOUS_START_ADDR_AFTER_INIT 0x1C000000
|
#define FLASH_CONTIGIOUS_START_ADDR_AFTER_INIT 0x1C000000
|
||||||
#define FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT 0x1F000000
|
#define FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT 0x1F000000
|
||||||
@ -414,76 +405,5 @@ extern int bcmflash_raw_writenoerase(unsigned int flash_id, unsigned int offset,
|
|||||||
|
|
||||||
#define FIELD_OFFSET_IN_HEADER(HeaderPointer,Field) ((PUCHAR)&((HeaderPointer)(NULL))->Field - (PUCHAR)(NULL))
|
#define FIELD_OFFSET_IN_HEADER(HeaderPointer,Field) ((PUCHAR)&((HeaderPointer)(NULL))->Field - (PUCHAR)(NULL))
|
||||||
|
|
||||||
#if 0
|
|
||||||
INT BeceemEEPROMBulkRead(
|
|
||||||
PMINI_ADAPTER Adapter,
|
|
||||||
PUINT pBuffer,
|
|
||||||
UINT uiOffset,
|
|
||||||
UINT uiNumBytes);
|
|
||||||
|
|
||||||
|
|
||||||
INT BeceemFlashBulkRead(
|
|
||||||
PMINI_ADAPTER Adapter,
|
|
||||||
PUINT pBuffer,
|
|
||||||
UINT uiOffset,
|
|
||||||
UINT uiNumBytes);
|
|
||||||
|
|
||||||
UINT BcmGetEEPROMSize(PMINI_ADAPTER Adapter);
|
|
||||||
|
|
||||||
UINT BcmGetFlashSize(PMINI_ADAPTER Adapter);
|
|
||||||
|
|
||||||
UINT BcmGetFlashSectorSize(PMINI_ADAPTER Adapter);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
INT BeceemFlashBulkWrite(
|
|
||||||
PMINI_ADAPTER Adapter,
|
|
||||||
PUINT pBuffer,
|
|
||||||
UINT uiOffset,
|
|
||||||
UINT uiNumBytes,
|
|
||||||
BOOLEAN bVerify);
|
|
||||||
|
|
||||||
INT PropagateCalParamsFromFlashToMemory(PMINI_ADAPTER Adapter);
|
|
||||||
|
|
||||||
INT PropagateCalParamsFromEEPROMToMemory(PMINI_ADAPTER Adapter);
|
|
||||||
|
|
||||||
|
|
||||||
INT BeceemEEPROMBulkWrite(
|
|
||||||
PMINI_ADAPTER Adapter,
|
|
||||||
PUCHAR pBuffer,
|
|
||||||
UINT uiOffset,
|
|
||||||
UINT uiNumBytes,
|
|
||||||
BOOLEAN bVerify);
|
|
||||||
|
|
||||||
|
|
||||||
INT ReadBeceemEEPROM(PMINI_ADAPTER Adapter,UINT dwAddress, UINT *pdwData);
|
|
||||||
|
|
||||||
NVM_TYPE BcmGetNvmType(PMINI_ADAPTER Adapter);
|
|
||||||
|
|
||||||
INT BeceemNVMRead(
|
|
||||||
PMINI_ADAPTER Adapter,
|
|
||||||
PUINT pBuffer,
|
|
||||||
UINT uiOffset,
|
|
||||||
UINT uiNumBytes);
|
|
||||||
|
|
||||||
INT BeceemNVMWrite(
|
|
||||||
PMINI_ADAPTER Adapter,
|
|
||||||
PUINT pBuffer,
|
|
||||||
UINT uiOffset,
|
|
||||||
UINT uiNumBytes,
|
|
||||||
BOOLEAN bVerify);
|
|
||||||
|
|
||||||
INT ReadMacAddressFromEEPROM(PMINI_ADAPTER Adapter);
|
|
||||||
|
|
||||||
INT BcmUpdateSectorSize(PMINI_ADAPTER Adapter,UINT uiSectorSize);
|
|
||||||
|
|
||||||
INT BcmInitNVM(PMINI_ADAPTER Adapter);
|
|
||||||
|
|
||||||
VOID BcmValidateNvmType(PMINI_ADAPTER Adapter);
|
|
||||||
|
|
||||||
VOID BcmGetFlashCSInfo(PMINI_ADAPTER Adapter);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1,49 +0,0 @@
|
|||||||
/*++
|
|
||||||
|
|
||||||
Copyright (c) Beceem Communications Inc.
|
|
||||||
|
|
||||||
Module Name:
|
|
||||||
OSAL_Misc.h
|
|
||||||
|
|
||||||
Abstract:
|
|
||||||
Provides the OS Abstracted macros to access:
|
|
||||||
Linked Lists
|
|
||||||
Dispatcher Objects(Events,Semaphores,Spin Locks and the like)
|
|
||||||
Files
|
|
||||||
|
|
||||||
|
|
||||||
Revision History:
|
|
||||||
Who When What
|
|
||||||
-------- -------- ----------------------------------------------
|
|
||||||
Name Date Created/reviewed/modified
|
|
||||||
Rajeev 24/1/08 Created
|
|
||||||
Notes:
|
|
||||||
|
|
||||||
--*/
|
|
||||||
#ifndef _OSAL_MISC_H_
|
|
||||||
#define _OSAL_MISC_H_
|
|
||||||
//OSAL Macros
|
|
||||||
//OSAL Primitives
|
|
||||||
typedef PUCHAR POSAL_NW_PACKET ; //Nw packets
|
|
||||||
|
|
||||||
|
|
||||||
#define OsalMemAlloc(n,t) kmalloc(n,GFP_KERNEL)
|
|
||||||
|
|
||||||
#define OsalMemFree(x,n) bcm_kfree(x)
|
|
||||||
|
|
||||||
#define OsalMemMove(dest, src, len) \
|
|
||||||
{ \
|
|
||||||
memcpy(dest,src, len); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define OsalZeroMemory(pDest, Len) \
|
|
||||||
{ \
|
|
||||||
memset(pDest,0,Len); \
|
|
||||||
}
|
|
||||||
|
|
||||||
//#define OsalMemSet(pSrc,Char,Len) memset(pSrc,Char,Len)
|
|
||||||
|
|
||||||
bool OsalMemCompare(void *dest, void *src, UINT len);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -43,14 +43,8 @@ Firmware is available from the Linux firmware repository at:
|
|||||||
http://git.kernel.org/?p=linux/kernel/git/dwmw2/linux-firmware.git
|
http://git.kernel.org/?p=linux/kernel/git/dwmw2/linux-firmware.git
|
||||||
https://git.kernel.org/?p=linux/kernel/git/dwmw2/linux-firmware.git
|
https://git.kernel.org/?p=linux/kernel/git/dwmw2/linux-firmware.git
|
||||||
|
|
||||||
For all chips, copy brcm/bcm43xx-0-610-809-0.fw and
|
For all chips, copy brcm/bcm43xx-0.fw and brcm/bcm43xx_hdr-0.fw to
|
||||||
brcm/bcm43xx_hdr-0-610-809-0.fw to /lib/firmware/brcm (or wherever firmware is
|
/lib/firmware/brcm (or wherever firmware is normally installed on your system).
|
||||||
normally installed on the system). In the /lib/firmware/brcm directory, then
|
|
||||||
create the following symlinks:
|
|
||||||
|
|
||||||
ln -s bcm43xx-0-610-809-0.fw bcm43xx-0.fw
|
|
||||||
ln -s bcm43xx_hdr-0-610-809-0.fw bcm43xx_hdr-0.fw
|
|
||||||
|
|
||||||
|
|
||||||
Currently supported chips
|
Currently supported chips
|
||||||
==============
|
==============
|
||||||
|
@ -25,8 +25,9 @@ Firmware is available from the Linux firmware repository at:
|
|||||||
http://git.kernel.org/?p=linux/kernel/git/dwmw2/linux-firmware.git
|
http://git.kernel.org/?p=linux/kernel/git/dwmw2/linux-firmware.git
|
||||||
https://git.kernel.org/?p=linux/kernel/git/dwmw2/linux-firmware.git
|
https://git.kernel.org/?p=linux/kernel/git/dwmw2/linux-firmware.git
|
||||||
|
|
||||||
For 4329 chip, copy brcm/bcm4329-fullmac-4-218-248-5.bin and
|
For 4329 chip, copy brcm/bcm4329-fullmac-4.bin and brcm/bcm4329-fullmac-4.txt
|
||||||
bcm4329-fullmac-4-218-248-5.txt to /lib/firmware/brcm
|
to /lib/firmware/brcm (or wherever firmware is normally installed on your
|
||||||
|
system).
|
||||||
|
|
||||||
Contact Info:
|
Contact Info:
|
||||||
=============
|
=============
|
||||||
|
@ -16,13 +16,14 @@
|
|||||||
/* ****************** BCMSDH Interface Functions *************************** */
|
/* ****************** BCMSDH Interface Functions *************************** */
|
||||||
|
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
#include <linux/netdevice.h>
|
||||||
#include <bcmdefs.h>
|
#include <bcmdefs.h>
|
||||||
#include <bcmdevs.h>
|
#include <bcmdevs.h>
|
||||||
#include <bcmendian.h>
|
#include <bcmendian.h>
|
||||||
|
#include <osl.h>
|
||||||
#include <bcmutils.h>
|
#include <bcmutils.h>
|
||||||
#include <hndsoc.h>
|
#include <hndsoc.h>
|
||||||
#include <siutils.h>
|
#include <siutils.h>
|
||||||
#include <osl.h>
|
|
||||||
|
|
||||||
#include <bcmsdh.h> /* BRCM API for SDIO
|
#include <bcmsdh.h> /* BRCM API for SDIO
|
||||||
clients (such as wl, dhd) */
|
clients (such as wl, dhd) */
|
||||||
@ -38,7 +39,7 @@ struct bcmsdh_info {
|
|||||||
bool init_success; /* underlying driver successfully attached */
|
bool init_success; /* underlying driver successfully attached */
|
||||||
void *sdioh; /* handler for sdioh */
|
void *sdioh; /* handler for sdioh */
|
||||||
u32 vendevid; /* Target Vendor and Device ID on SD bus */
|
u32 vendevid; /* Target Vendor and Device ID on SD bus */
|
||||||
osl_t *osh;
|
struct osl_info *osh;
|
||||||
bool regfail; /* Save status of last
|
bool regfail; /* Save status of last
|
||||||
reg_read/reg_write call */
|
reg_read/reg_write call */
|
||||||
u32 sbwad; /* Save backplane window address */
|
u32 sbwad; /* Save backplane window address */
|
||||||
@ -55,7 +56,8 @@ void bcmsdh_enable_hw_oob_intr(bcmsdh_info_t *sdh, bool enable)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bcmsdh_info_t *bcmsdh_attach(osl_t *osh, void *cfghdl, void **regsva, uint irq)
|
bcmsdh_info_t *bcmsdh_attach(struct osl_info *osh, void *cfghdl,
|
||||||
|
void **regsva, uint irq)
|
||||||
{
|
{
|
||||||
bcmsdh_info_t *bcmsdh;
|
bcmsdh_info_t *bcmsdh;
|
||||||
|
|
||||||
@ -84,7 +86,7 @@ bcmsdh_info_t *bcmsdh_attach(osl_t *osh, void *cfghdl, void **regsva, uint irq)
|
|||||||
return bcmsdh;
|
return bcmsdh;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bcmsdh_detach(osl_t *osh, void *sdh)
|
int bcmsdh_detach(struct osl_info *osh, void *sdh)
|
||||||
{
|
{
|
||||||
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
|
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
|
||||||
|
|
||||||
@ -451,7 +453,7 @@ bool bcmsdh_regfail(void *sdh)
|
|||||||
|
|
||||||
int
|
int
|
||||||
bcmsdh_recv_buf(void *sdh, u32 addr, uint fn, uint flags,
|
bcmsdh_recv_buf(void *sdh, u32 addr, uint fn, uint flags,
|
||||||
u8 *buf, uint nbytes, void *pkt,
|
u8 *buf, uint nbytes, struct sk_buff *pkt,
|
||||||
bcmsdh_cmplt_fn_t complete, void *handle)
|
bcmsdh_cmplt_fn_t complete, void *handle)
|
||||||
{
|
{
|
||||||
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
|
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
|
||||||
|
@ -20,8 +20,7 @@
|
|||||||
|
|
||||||
#define __UNDEF_NO_VERSION__
|
#define __UNDEF_NO_VERSION__
|
||||||
|
|
||||||
#include <linuxver.h>
|
#include <linux/netdevice.h>
|
||||||
|
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <linux/completion.h>
|
#include <linux/completion.h>
|
||||||
|
|
||||||
@ -57,7 +56,7 @@ struct bcmsdh_hc {
|
|||||||
#else
|
#else
|
||||||
struct pci_dev *dev; /* pci device handle */
|
struct pci_dev *dev; /* pci device handle */
|
||||||
#endif /* BCMPLATFORM_BUS */
|
#endif /* BCMPLATFORM_BUS */
|
||||||
osl_t *osh;
|
struct osl_info *osh;
|
||||||
void *regs; /* SDIO Host Controller address */
|
void *regs; /* SDIO Host Controller address */
|
||||||
bcmsdh_info_t *sdh; /* SDIO Host Controller handle */
|
bcmsdh_info_t *sdh; /* SDIO Host Controller handle */
|
||||||
void *ch;
|
void *ch;
|
||||||
@ -138,23 +137,12 @@ static int __devinit bcmsdh_probe(struct device *dev);
|
|||||||
static int __devexit bcmsdh_remove(struct device *dev);
|
static int __devexit bcmsdh_remove(struct device *dev);
|
||||||
#endif /* BCMLXSDMMC */
|
#endif /* BCMLXSDMMC */
|
||||||
|
|
||||||
#ifndef BCMLXSDMMC
|
|
||||||
static struct device_driver bcmsdh_driver = {
|
|
||||||
.name = "pxa2xx-mci",
|
|
||||||
.bus = &platform_bus_type,
|
|
||||||
.probe = bcmsdh_probe,
|
|
||||||
.remove = bcmsdh_remove,
|
|
||||||
.suspend = NULL,
|
|
||||||
.resume = NULL,
|
|
||||||
};
|
|
||||||
#endif /* BCMLXSDMMC */
|
|
||||||
|
|
||||||
#ifndef BCMLXSDMMC
|
#ifndef BCMLXSDMMC
|
||||||
static
|
static
|
||||||
#endif /* BCMLXSDMMC */
|
#endif /* BCMLXSDMMC */
|
||||||
int bcmsdh_probe(struct device *dev)
|
int bcmsdh_probe(struct device *dev)
|
||||||
{
|
{
|
||||||
osl_t *osh = NULL;
|
struct osl_info *osh = NULL;
|
||||||
bcmsdh_hc_t *sdhc = NULL;
|
bcmsdh_hc_t *sdhc = NULL;
|
||||||
unsigned long regs = 0;
|
unsigned long regs = 0;
|
||||||
bcmsdh_info_t *sdh = NULL;
|
bcmsdh_info_t *sdh = NULL;
|
||||||
@ -189,7 +177,7 @@ int bcmsdh_probe(struct device *dev)
|
|||||||
}
|
}
|
||||||
#endif /* defined(OOB_INTR_ONLY) */
|
#endif /* defined(OOB_INTR_ONLY) */
|
||||||
/* allocate SDIO Host Controller state info */
|
/* allocate SDIO Host Controller state info */
|
||||||
osh = osl_attach(dev, PCI_BUS, false);
|
osh = osl_attach(dev, PCI_BUS);
|
||||||
if (!osh) {
|
if (!osh) {
|
||||||
SDLX_MSG(("%s: osl_attach failed\n", __func__));
|
SDLX_MSG(("%s: osl_attach failed\n", __func__));
|
||||||
goto err;
|
goto err;
|
||||||
@ -258,7 +246,7 @@ static
|
|||||||
int bcmsdh_remove(struct device *dev)
|
int bcmsdh_remove(struct device *dev)
|
||||||
{
|
{
|
||||||
bcmsdh_hc_t *sdhc, *prev;
|
bcmsdh_hc_t *sdhc, *prev;
|
||||||
osl_t *osh;
|
struct osl_info *osh;
|
||||||
|
|
||||||
sdhc = sdhcinfo;
|
sdhc = sdhcinfo;
|
||||||
drvinfo.detach(sdhc->ch);
|
drvinfo.detach(sdhc->ch);
|
||||||
@ -291,269 +279,23 @@ int bcmsdh_remove(struct device *dev)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* BCMPLATFORM_BUS */
|
|
||||||
|
|
||||||
#if !defined(BCMLXSDMMC)
|
|
||||||
/* forward declarations for PCI probe and remove functions. */
|
|
||||||
static int __devinit bcmsdh_pci_probe(struct pci_dev *pdev,
|
|
||||||
const struct pci_device_id *ent);
|
|
||||||
static void __devexit bcmsdh_pci_remove(struct pci_dev *pdev);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* pci id table
|
|
||||||
*/
|
|
||||||
static struct pci_device_id bcmsdh_pci_devid[] __devinitdata = {
|
|
||||||
{
|
|
||||||
.vendor = PCI_ANY_ID,
|
|
||||||
.device = PCI_ANY_ID,
|
|
||||||
.subvendor = PCI_ANY_ID,
|
|
||||||
.subdevice = PCI_ANY_ID,
|
|
||||||
.class = 0,
|
|
||||||
.class_mask = 0,
|
|
||||||
.driver_data = 0,
|
|
||||||
},
|
|
||||||
{0,}
|
|
||||||
};
|
|
||||||
|
|
||||||
MODULE_DEVICE_TABLE(pci, bcmsdh_pci_devid);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SDIO Host Controller pci driver info
|
|
||||||
*/
|
|
||||||
static struct pci_driver bcmsdh_pci_driver = {
|
|
||||||
.node = {},
|
|
||||||
.name = "bcmsdh",
|
|
||||||
.id_table = bcmsdh_pci_devid,
|
|
||||||
.probe = bcmsdh_pci_probe,
|
|
||||||
.remove = bcmsdh_pci_remove,
|
|
||||||
.suspend = NULL,
|
|
||||||
.resume = NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
extern uint sd_pci_slot; /* Force detection to a particular PCI */
|
|
||||||
/* slot only . Allows for having multiple */
|
|
||||||
/* WL devices at once in a PC */
|
|
||||||
/* Only one instance of dhd will be */
|
|
||||||
/* usable at a time */
|
|
||||||
/* Upper word is bus number, */
|
|
||||||
/* lower word is slot number */
|
|
||||||
/* Default value of 0xFFFFffff turns this */
|
|
||||||
/* off */
|
|
||||||
module_param(sd_pci_slot, uint, 0);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Detect supported SDIO Host Controller and attach if found.
|
|
||||||
*
|
|
||||||
* Determine if the device described by pdev is a supported SDIO Host
|
|
||||||
* Controller. If so, attach to it and attach to the target device.
|
|
||||||
*/
|
|
||||||
static int __devinit
|
|
||||||
bcmsdh_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|
||||||
{
|
|
||||||
osl_t *osh = NULL;
|
|
||||||
bcmsdh_hc_t *sdhc = NULL;
|
|
||||||
unsigned long regs;
|
|
||||||
bcmsdh_info_t *sdh = NULL;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
if (sd_pci_slot != 0xFFFFffff) {
|
|
||||||
if (pdev->bus->number != (sd_pci_slot >> 16) ||
|
|
||||||
PCI_SLOT(pdev->devfn) != (sd_pci_slot & 0xffff)) {
|
|
||||||
SDLX_MSG(("%s: %s: bus %X, slot %X, vend %X, dev %X\n",
|
|
||||||
__func__,
|
|
||||||
bcmsdh_chipmatch(pdev->vendor, pdev->device) ?
|
|
||||||
"Found compatible SDIOHC" :
|
|
||||||
"Probing unknown device",
|
|
||||||
pdev->bus->number, PCI_SLOT(pdev->devfn),
|
|
||||||
pdev->vendor, pdev->device));
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
SDLX_MSG(("%s: %s: bus %X, slot %X, vendor %X, device %X "
|
|
||||||
"(good PCI location)\n", __func__,
|
|
||||||
bcmsdh_chipmatch(pdev->vendor, pdev->device) ?
|
|
||||||
"Using compatible SDIOHC" : "WARNING, forced use "
|
|
||||||
"of unkown device",
|
|
||||||
pdev->bus->number, PCI_SLOT(pdev->devfn), pdev->vendor,
|
|
||||||
pdev->device));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((pdev->vendor == VENDOR_TI)
|
|
||||||
&& ((pdev->device == PCIXX21_FLASHMEDIA_ID)
|
|
||||||
|| (pdev->device == PCIXX21_FLASHMEDIA0_ID))) {
|
|
||||||
u32 config_reg;
|
|
||||||
|
|
||||||
SDLX_MSG(("%s: Disabling TI FlashMedia Controller.\n",
|
|
||||||
__func__));
|
|
||||||
osh = osl_attach(pdev, PCI_BUS, false);
|
|
||||||
if (!osh) {
|
|
||||||
SDLX_MSG(("%s: osl_attach failed\n", __func__));
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
config_reg = OSL_PCI_READ_CONFIG(osh, 0x4c, 4);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set MMC_SD_DIS bit in FlashMedia Controller.
|
|
||||||
* Disbling the SD/MMC Controller in the FlashMedia Controller
|
|
||||||
* allows the Standard SD Host Controller to take over control
|
|
||||||
* of the SD Slot.
|
|
||||||
*/
|
|
||||||
config_reg |= 0x02;
|
|
||||||
OSL_PCI_WRITE_CONFIG(osh, 0x4c, 4, config_reg);
|
|
||||||
osl_detach(osh);
|
|
||||||
}
|
|
||||||
/* match this pci device with what we support */
|
|
||||||
/* we can't solely rely on this to believe it is
|
|
||||||
our SDIO Host Controller! */
|
|
||||||
if (!bcmsdh_chipmatch(pdev->vendor, pdev->device))
|
|
||||||
return -ENODEV;
|
|
||||||
|
|
||||||
/* this is a pci device we might support */
|
|
||||||
SDLX_MSG(("%s: Found possible SDIO Host Controller: "
|
|
||||||
"bus %d slot %d func %d irq %d\n", __func__,
|
|
||||||
pdev->bus->number, PCI_SLOT(pdev->devfn),
|
|
||||||
PCI_FUNC(pdev->devfn), pdev->irq));
|
|
||||||
|
|
||||||
/* use bcmsdh_query_device() to get the vendor ID of the target device
|
|
||||||
* so it will eventually appear in the Broadcom string on the console
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* allocate SDIO Host Controller state info */
|
|
||||||
osh = osl_attach(pdev, PCI_BUS, false);
|
|
||||||
if (!osh) {
|
|
||||||
SDLX_MSG(("%s: osl_attach failed\n", __func__));
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
sdhc = kzalloc(sizeof(bcmsdh_hc_t), GFP_ATOMIC);
|
|
||||||
if (!sdhc) {
|
|
||||||
SDLX_MSG(("%s: out of memory\n", __func__));
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
sdhc->osh = osh;
|
|
||||||
|
|
||||||
sdhc->dev = pdev;
|
|
||||||
|
|
||||||
/* map to address where host can access */
|
|
||||||
pci_set_master(pdev);
|
|
||||||
rc = pci_enable_device(pdev);
|
|
||||||
if (rc) {
|
|
||||||
SDLX_MSG(("%s: Cannot enable PCI device\n", __func__));
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
sdh = bcmsdh_attach(osh, (void *)(unsigned long)pci_resource_start(pdev, 0),
|
|
||||||
(void **)®s, pdev->irq);
|
|
||||||
if (!sdh) {
|
|
||||||
SDLX_MSG(("%s: bcmsdh_attach failed\n", __func__));
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
sdhc->sdh = sdh;
|
|
||||||
|
|
||||||
/* try to attach to the target device */
|
|
||||||
sdhc->ch = drvinfo.attach(VENDOR_BROADCOM, /* pdev->vendor, */
|
|
||||||
bcmsdh_query_device(sdh) & 0xFFFF, 0, 0, 0, 0,
|
|
||||||
(void *)regs, NULL, sdh);
|
|
||||||
if (!sdhc->ch) {
|
|
||||||
SDLX_MSG(("%s: device attach failed\n", __func__));
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* chain SDIO Host Controller info together */
|
|
||||||
sdhc->next = sdhcinfo;
|
|
||||||
sdhcinfo = sdhc;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* error handling */
|
|
||||||
err:
|
|
||||||
if (sdhc->sdh)
|
|
||||||
bcmsdh_detach(sdhc->osh, sdhc->sdh);
|
|
||||||
if (sdhc)
|
|
||||||
kfree(sdhc);
|
|
||||||
if (osh)
|
|
||||||
osl_detach(osh);
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Detach from target devices and SDIO Host Controller
|
|
||||||
*/
|
|
||||||
static void __devexit bcmsdh_pci_remove(struct pci_dev *pdev)
|
|
||||||
{
|
|
||||||
bcmsdh_hc_t *sdhc, *prev;
|
|
||||||
osl_t *osh;
|
|
||||||
|
|
||||||
/* find the SDIO Host Controller state for this
|
|
||||||
pdev and take it out from the list */
|
|
||||||
for (sdhc = sdhcinfo, prev = NULL; sdhc; sdhc = sdhc->next) {
|
|
||||||
if (sdhc->dev == pdev) {
|
|
||||||
if (prev)
|
|
||||||
prev->next = sdhc->next;
|
|
||||||
else
|
|
||||||
sdhcinfo = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
prev = sdhc;
|
|
||||||
}
|
|
||||||
if (!sdhc)
|
|
||||||
return;
|
|
||||||
|
|
||||||
drvinfo.detach(sdhc->ch);
|
|
||||||
|
|
||||||
bcmsdh_detach(sdhc->osh, sdhc->sdh);
|
|
||||||
|
|
||||||
/* release SDIO Host Controller info */
|
|
||||||
osh = sdhc->osh;
|
|
||||||
kfree(sdhc);
|
|
||||||
osl_detach(osh);
|
|
||||||
}
|
|
||||||
#endif /* BCMLXSDMMC */
|
|
||||||
#endif /* BCMPLATFORM_BUS */
|
#endif /* BCMPLATFORM_BUS */
|
||||||
|
|
||||||
extern int sdio_function_init(void);
|
extern int sdio_function_init(void);
|
||||||
|
|
||||||
int bcmsdh_register(bcmsdh_driver_t *driver)
|
int bcmsdh_register(bcmsdh_driver_t *driver)
|
||||||
{
|
{
|
||||||
int error = 0;
|
|
||||||
|
|
||||||
drvinfo = *driver;
|
drvinfo = *driver;
|
||||||
|
|
||||||
#if defined(BCMPLATFORM_BUS)
|
|
||||||
#if defined(BCMLXSDMMC)
|
|
||||||
SDLX_MSG(("Linux Kernel SDIO/MMC Driver\n"));
|
SDLX_MSG(("Linux Kernel SDIO/MMC Driver\n"));
|
||||||
error = sdio_function_init();
|
return sdio_function_init();
|
||||||
#else
|
|
||||||
SDLX_MSG(("Intel PXA270 SDIO Driver\n"));
|
|
||||||
error = driver_register(&bcmsdh_driver);
|
|
||||||
#endif /* defined(BCMLXSDMMC) */
|
|
||||||
return error;
|
|
||||||
#endif /* defined(BCMPLATFORM_BUS) */
|
|
||||||
|
|
||||||
#if !defined(BCMPLATFORM_BUS) && !defined(BCMLXSDMMC)
|
|
||||||
error = pci_register_driver(&bcmsdh_pci_driver);
|
|
||||||
if (!error)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
SDLX_MSG(("%s: pci_register_driver failed 0x%x\n", __func__, error));
|
|
||||||
#endif /* BCMPLATFORM_BUS */
|
|
||||||
|
|
||||||
return error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void sdio_function_cleanup(void);
|
extern void sdio_function_cleanup(void);
|
||||||
|
|
||||||
void bcmsdh_unregister(void)
|
void bcmsdh_unregister(void)
|
||||||
{
|
{
|
||||||
#if defined(BCMPLATFORM_BUS) && !defined(BCMLXSDMMC)
|
|
||||||
driver_unregister(&bcmsdh_driver);
|
|
||||||
#endif
|
|
||||||
#if defined(BCMLXSDMMC)
|
|
||||||
sdio_function_cleanup();
|
sdio_function_cleanup();
|
||||||
#endif /* BCMLXSDMMC */
|
|
||||||
#if !defined(BCMPLATFORM_BUS) && !defined(BCMLXSDMMC)
|
|
||||||
pci_unregister_driver(&bcmsdh_pci_driver);
|
|
||||||
#endif /* BCMPLATFORM_BUS */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(OOB_INTR_ONLY)
|
#if defined(OOB_INTR_ONLY)
|
||||||
|
@ -14,11 +14,12 @@
|
|||||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
#include <linux/netdevice.h>
|
||||||
#include <bcmdefs.h>
|
#include <bcmdefs.h>
|
||||||
#include <bcmdevs.h>
|
#include <bcmdevs.h>
|
||||||
#include <bcmendian.h>
|
#include <bcmendian.h>
|
||||||
#include <bcmutils.h>
|
|
||||||
#include <osl.h>
|
#include <osl.h>
|
||||||
|
#include <bcmutils.h>
|
||||||
#include <sdio.h> /* SDIO Device and Protocol Specs */
|
#include <sdio.h> /* SDIO Device and Protocol Specs */
|
||||||
#include <sdioh.h> /* SDIO Host Controller Specification */
|
#include <sdioh.h> /* SDIO Host Controller Specification */
|
||||||
#include <bcmsdbus.h> /* bcmsdh to/from specific controller APIs */
|
#include <bcmsdbus.h> /* bcmsdh to/from specific controller APIs */
|
||||||
@ -111,7 +112,7 @@ static int sdioh_sdmmc_card_enablefuncs(sdioh_info_t *sd)
|
|||||||
/*
|
/*
|
||||||
* Public entry points & extern's
|
* Public entry points & extern's
|
||||||
*/
|
*/
|
||||||
extern sdioh_info_t *sdioh_attach(osl_t *osh, void *bar0, uint irq)
|
extern sdioh_info_t *sdioh_attach(struct osl_info *osh, void *bar0, uint irq)
|
||||||
{
|
{
|
||||||
sdioh_info_t *sd;
|
sdioh_info_t *sd;
|
||||||
int err_ret;
|
int err_ret;
|
||||||
@ -174,7 +175,7 @@ extern sdioh_info_t *sdioh_attach(osl_t *osh, void *bar0, uint irq)
|
|||||||
return sd;
|
return sd;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern SDIOH_API_RC sdioh_detach(osl_t *osh, sdioh_info_t *sd)
|
extern SDIOH_API_RC sdioh_detach(struct osl_info *osh, sdioh_info_t *sd)
|
||||||
{
|
{
|
||||||
sd_trace(("%s\n", __func__));
|
sd_trace(("%s\n", __func__));
|
||||||
|
|
||||||
@ -750,7 +751,7 @@ sdioh_cis_read(sdioh_info_t *sd, uint func, u8 *cisd, u32 length)
|
|||||||
sd_trace(("%s: Func = %d\n", __func__, func));
|
sd_trace(("%s: Func = %d\n", __func__, func));
|
||||||
|
|
||||||
if (!sd->func_cis_ptr[func]) {
|
if (!sd->func_cis_ptr[func]) {
|
||||||
bzero(cis, length);
|
memset(cis, 0, length);
|
||||||
sd_err(("%s: no func_cis_ptr[%d]\n", __func__, func));
|
sd_err(("%s: no func_cis_ptr[%d]\n", __func__, func));
|
||||||
return SDIOH_API_RC_FAIL;
|
return SDIOH_API_RC_FAIL;
|
||||||
}
|
}
|
||||||
@ -927,13 +928,13 @@ sdioh_request_word(sdioh_info_t *sd, uint cmd_type, uint rw, uint func,
|
|||||||
|
|
||||||
static SDIOH_API_RC
|
static SDIOH_API_RC
|
||||||
sdioh_request_packet(sdioh_info_t *sd, uint fix_inc, uint write, uint func,
|
sdioh_request_packet(sdioh_info_t *sd, uint fix_inc, uint write, uint func,
|
||||||
uint addr, void *pkt)
|
uint addr, struct sk_buff *pkt)
|
||||||
{
|
{
|
||||||
bool fifo = (fix_inc == SDIOH_DATA_FIX);
|
bool fifo = (fix_inc == SDIOH_DATA_FIX);
|
||||||
u32 SGCount = 0;
|
u32 SGCount = 0;
|
||||||
int err_ret = 0;
|
int err_ret = 0;
|
||||||
|
|
||||||
void *pnext;
|
struct sk_buff *pnext;
|
||||||
|
|
||||||
sd_trace(("%s: Enter\n", __func__));
|
sd_trace(("%s: Enter\n", __func__));
|
||||||
|
|
||||||
@ -943,8 +944,8 @@ sdioh_request_packet(sdioh_info_t *sd, uint fix_inc, uint write, uint func,
|
|||||||
|
|
||||||
/* Claim host controller */
|
/* Claim host controller */
|
||||||
sdio_claim_host(gInstance->func[func]);
|
sdio_claim_host(gInstance->func[func]);
|
||||||
for (pnext = pkt; pnext; pnext = PKTNEXT(pnext)) {
|
for (pnext = pkt; pnext; pnext = pnext->next) {
|
||||||
uint pkt_len = PKTLEN(pnext);
|
uint pkt_len = pnext->len;
|
||||||
pkt_len += 3;
|
pkt_len += 3;
|
||||||
pkt_len &= 0xFFFFFFFC;
|
pkt_len &= 0xFFFFFFFC;
|
||||||
|
|
||||||
@ -961,23 +962,23 @@ sdioh_request_packet(sdioh_info_t *sd, uint fix_inc, uint write, uint func,
|
|||||||
* is supposed to give
|
* is supposed to give
|
||||||
* us something we can work with.
|
* us something we can work with.
|
||||||
*/
|
*/
|
||||||
ASSERT(((u32) (PKTDATA(pkt)) & DMA_ALIGN_MASK) == 0);
|
ASSERT(((u32) (pkt->data) & DMA_ALIGN_MASK) == 0);
|
||||||
|
|
||||||
if ((write) && (!fifo)) {
|
if ((write) && (!fifo)) {
|
||||||
err_ret = sdio_memcpy_toio(gInstance->func[func], addr,
|
err_ret = sdio_memcpy_toio(gInstance->func[func], addr,
|
||||||
((u8 *) PKTDATA(pnext)),
|
((u8 *) (pnext->data)),
|
||||||
pkt_len);
|
pkt_len);
|
||||||
} else if (write) {
|
} else if (write) {
|
||||||
err_ret = sdio_memcpy_toio(gInstance->func[func], addr,
|
err_ret = sdio_memcpy_toio(gInstance->func[func], addr,
|
||||||
((u8 *) PKTDATA(pnext)),
|
((u8 *) (pnext->data)),
|
||||||
pkt_len);
|
pkt_len);
|
||||||
} else if (fifo) {
|
} else if (fifo) {
|
||||||
err_ret = sdio_readsb(gInstance->func[func],
|
err_ret = sdio_readsb(gInstance->func[func],
|
||||||
((u8 *) PKTDATA(pnext)),
|
((u8 *) (pnext->data)),
|
||||||
addr, pkt_len);
|
addr, pkt_len);
|
||||||
} else {
|
} else {
|
||||||
err_ret = sdio_memcpy_fromio(gInstance->func[func],
|
err_ret = sdio_memcpy_fromio(gInstance->func[func],
|
||||||
((u8 *) PKTDATA(pnext)),
|
((u8 *) (pnext->data)),
|
||||||
addr, pkt_len);
|
addr, pkt_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1025,10 +1026,10 @@ sdioh_request_packet(sdioh_info_t *sd, uint fix_inc, uint write, uint func,
|
|||||||
extern SDIOH_API_RC
|
extern SDIOH_API_RC
|
||||||
sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write,
|
sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write,
|
||||||
uint func, uint addr, uint reg_width, uint buflen_u,
|
uint func, uint addr, uint reg_width, uint buflen_u,
|
||||||
u8 *buffer, void *pkt)
|
u8 *buffer, struct sk_buff *pkt)
|
||||||
{
|
{
|
||||||
SDIOH_API_RC Status;
|
SDIOH_API_RC Status;
|
||||||
void *mypkt = NULL;
|
struct sk_buff *mypkt = NULL;
|
||||||
|
|
||||||
sd_trace(("%s: Enter\n", __func__));
|
sd_trace(("%s: Enter\n", __func__));
|
||||||
|
|
||||||
@ -1038,52 +1039,52 @@ sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write,
|
|||||||
if (pkt == NULL) {
|
if (pkt == NULL) {
|
||||||
sd_data(("%s: Creating new %s Packet, len=%d\n",
|
sd_data(("%s: Creating new %s Packet, len=%d\n",
|
||||||
__func__, write ? "TX" : "RX", buflen_u));
|
__func__, write ? "TX" : "RX", buflen_u));
|
||||||
mypkt = PKTGET(sd->osh, buflen_u, write ? true : false);
|
mypkt = pkt_buf_get_skb(sd->osh, buflen_u);
|
||||||
if (!mypkt) {
|
if (!mypkt) {
|
||||||
sd_err(("%s: PKTGET failed: len %d\n",
|
sd_err(("%s: pkt_buf_get_skb failed: len %d\n",
|
||||||
__func__, buflen_u));
|
__func__, buflen_u));
|
||||||
return SDIOH_API_RC_FAIL;
|
return SDIOH_API_RC_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For a write, copy the buffer data into the packet. */
|
/* For a write, copy the buffer data into the packet. */
|
||||||
if (write)
|
if (write)
|
||||||
bcopy(buffer, PKTDATA(mypkt), buflen_u);
|
bcopy(buffer, mypkt->data, buflen_u);
|
||||||
|
|
||||||
Status =
|
Status =
|
||||||
sdioh_request_packet(sd, fix_inc, write, func, addr, mypkt);
|
sdioh_request_packet(sd, fix_inc, write, func, addr, mypkt);
|
||||||
|
|
||||||
/* For a read, copy the packet data back to the buffer. */
|
/* For a read, copy the packet data back to the buffer. */
|
||||||
if (!write)
|
if (!write)
|
||||||
bcopy(PKTDATA(mypkt), buffer, buflen_u);
|
bcopy(mypkt->data, buffer, buflen_u);
|
||||||
|
|
||||||
PKTFREE(sd->osh, mypkt, write ? true : false);
|
pkt_buf_free_skb(sd->osh, mypkt, write ? true : false);
|
||||||
} else if (((u32) (PKTDATA(pkt)) & DMA_ALIGN_MASK) != 0) {
|
} else if (((u32) (pkt->data) & DMA_ALIGN_MASK) != 0) {
|
||||||
/* Case 2: We have a packet, but it is unaligned. */
|
/* Case 2: We have a packet, but it is unaligned. */
|
||||||
|
|
||||||
/* In this case, we cannot have a chain. */
|
/* In this case, we cannot have a chain. */
|
||||||
ASSERT(PKTNEXT(pkt) == NULL);
|
ASSERT(pkt->next == NULL);
|
||||||
|
|
||||||
sd_data(("%s: Creating aligned %s Packet, len=%d\n",
|
sd_data(("%s: Creating aligned %s Packet, len=%d\n",
|
||||||
__func__, write ? "TX" : "RX", PKTLEN(pkt)));
|
__func__, write ? "TX" : "RX", pkt->len));
|
||||||
mypkt = PKTGET(sd->osh, PKTLEN(pkt), write ? true : false);
|
mypkt = pkt_buf_get_skb(sd->osh, pkt->len);
|
||||||
if (!mypkt) {
|
if (!mypkt) {
|
||||||
sd_err(("%s: PKTGET failed: len %d\n",
|
sd_err(("%s: pkt_buf_get_skb failed: len %d\n",
|
||||||
__func__, PKTLEN(pkt)));
|
__func__, pkt->len));
|
||||||
return SDIOH_API_RC_FAIL;
|
return SDIOH_API_RC_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For a write, copy the buffer data into the packet. */
|
/* For a write, copy the buffer data into the packet. */
|
||||||
if (write)
|
if (write)
|
||||||
bcopy(PKTDATA(pkt), PKTDATA(mypkt), PKTLEN(pkt));
|
bcopy(pkt->data, mypkt->data, pkt->len);
|
||||||
|
|
||||||
Status =
|
Status =
|
||||||
sdioh_request_packet(sd, fix_inc, write, func, addr, mypkt);
|
sdioh_request_packet(sd, fix_inc, write, func, addr, mypkt);
|
||||||
|
|
||||||
/* For a read, copy the packet data back to the buffer. */
|
/* For a read, copy the packet data back to the buffer. */
|
||||||
if (!write)
|
if (!write)
|
||||||
bcopy(PKTDATA(mypkt), PKTDATA(pkt), PKTLEN(mypkt));
|
bcopy(mypkt->data, pkt->data, mypkt->len);
|
||||||
|
|
||||||
PKTFREE(sd->osh, mypkt, write ? true : false);
|
pkt_buf_free_skb(sd->osh, mypkt, write ? true : false);
|
||||||
} else { /* case 3: We have a packet and
|
} else { /* case 3: We have a packet and
|
||||||
it is aligned. */
|
it is aligned. */
|
||||||
sd_data(("%s: Aligned %s Packet, direct DMA\n",
|
sd_data(("%s: Aligned %s Packet, direct DMA\n",
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user