1
0
Fork 0

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
wifi-calibration
Linus Torvalds 2011-01-10 16:04:53 -08:00
commit 949f6711b8
567 changed files with 51218 additions and 32353 deletions

View File

@ -1423,7 +1423,9 @@ F: drivers/net/tg3.*
BROADCOM BRCM80211 IEEE802.11n WIRELESS DRIVER
M: Brett Rudley <brudley@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
S: Supported
F: drivers/staging/brcm80211/

View File

@ -119,6 +119,8 @@ source "drivers/staging/vme/Kconfig"
source "drivers/staging/memrar/Kconfig"
source "drivers/staging/sep/Kconfig"
source "drivers/staging/iio/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/batman-adv/Kconfig"
source "drivers/staging/samsung-laptop/Kconfig"
source "drivers/staging/sm7xx/Kconfig"
@ -141,8 +141,6 @@ source "drivers/staging/cxt1e1/Kconfig"
source "drivers/staging/ti-st/Kconfig"
source "drivers/staging/adis16255/Kconfig"
source "drivers/staging/xgifb/Kconfig"
source "drivers/staging/msm/Kconfig"
@ -175,5 +173,9 @@ source "drivers/staging/intel_sst/Kconfig"
source "drivers/staging/speakup/Kconfig"
source "drivers/staging/cptm1217/Kconfig"
source "drivers/staging/ste_rmi4/Kconfig"
endif # !STAGING_EXCLUDE_BUILD
endif # STAGING

View File

@ -42,18 +42,17 @@ obj-$(CONFIG_VT6656) += vt6656/
obj-$(CONFIG_HYPERV) += hv/
obj-$(CONFIG_VME_BUS) += vme/
obj-$(CONFIG_MRST_RAR_HANDLER) += memrar/
obj-$(CONFIG_DX_SEP) += sep/
obj-$(CONFIG_IIO) += iio/
obj-$(CONFIG_ZRAM) += zram/
obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/
obj-$(CONFIG_WLAGS49_H25) += wlags49_h25/
obj-$(CONFIG_BATMAN_ADV) += batman-adv/
obj-$(CONFIG_SAMSUNG_LAPTOP) += samsung-laptop/
obj-$(CONFIG_FB_SM7XX) += sm7xx/
obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l/
obj-$(CONFIG_CRYSTALHD) += crystalhd/
obj-$(CONFIG_CXT1E1) += cxt1e1/
obj-$(CONFIG_TI_ST) += ti-st/
obj-$(CONFIG_ADIS16255) += adis16255/
obj-$(CONFIG_FB_XGI) += xgifb/
obj-$(CONFIG_MSM_STAGING) += msm/
obj-$(CONFIG_EASYCAP) += easycap/
@ -68,3 +67,5 @@ obj-$(CONFIG_BCM_WIMAX) += bcm/
obj-$(CONFIG_FT1000) += ft1000/
obj-$(CONFIG_SND_INTEL_SST) += intel_sst/
obj-$(CONFIG_SPEAKUP) += speakup/
obj-$(CONFIG_TOUCHSCREEN_CLEARPAD_TM1217) += cptm1217/
obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += ste_rmi4/

View File

@ -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.

View File

@ -1 +0,0 @@
obj-$(CONFIG_ADIS16255) += adis16255.o

View File

@ -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");

View File

@ -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

View File

@ -70,7 +70,7 @@ module_param(start_off, uint, 0644);
MODULE_PARM_DESC(start_off,
"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_G50,
PACK_MODE_LAST

View File

@ -876,7 +876,7 @@ HIFAckInterrupt(HIF_DEVICE *device)
void
HIFUnMaskInterrupt(HIF_DEVICE *device)
{
int ret;;
int ret;
AR_DEBUG_ASSERT(device != NULL);
AR_DEBUG_ASSERT(device->func != NULL);
@ -1188,7 +1188,7 @@ addHifDevice(struct sdio_func *func)
HIF_DEVICE *hifdevice;
AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: addHifDevice\n"));
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);
#if HIF_USE_DMA_BOUNCE_BUFFER
hifdevice->dma_buffer = kmalloc(HIF_DMA_BUFFER_SIZE, GFP_KERNEL);

View File

@ -4439,7 +4439,7 @@ skip_key:
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]));
sprintf(pos, "%2.2x", assocInfo[i]);
pos += 2;;
pos += 2;
}
AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n"));

View File

@ -30,7 +30,7 @@ void autofs_update_usage(struct autofs_dirhash *dh,
struct autofs_dir_ent *ent)
{
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,
@ -45,17 +45,18 @@ struct autofs_dir_ent *autofs_expire(struct super_block *sb,
struct path path;
int umount_ok;
if ( list_empty(&dh->expiry_head) || sbi->catatonic )
if (list_empty(&dh->expiry_head) || sbi->catatonic)
return NULL; /* No entries */
/* 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)
break;
/* Move to end of list in case expiry isn't desirable */
autofs_update_usage(dh, ent);
/* 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 */
/* Get the dentry for the autofs subdirectory */
@ -63,14 +64,15 @@ struct autofs_dir_ent *autofs_expire(struct super_block *sb,
if (!path.dentry) {
/* 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);
continue;
}
if (!path.dentry->d_inode) {
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);
autofs_delete_usage(ent);
continue;
@ -80,14 +82,16 @@ struct autofs_dir_ent *autofs_expire(struct super_block *sb,
point to the mounted-on-top root. */
if (!S_ISDIR(path.dentry->d_inode->i_mode) ||
!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;
}
path.mnt = mnt;
path_get(&path);
if (!follow_down(&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;
}
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);
if (umount_ok) {
DPRINTK(("autofs: signaling expire on %s\n", ent->name));
DPRINTK(("autofs: signaling expire on %s\n",
ent->name));
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 */
}
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 *));
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;
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 ) {
if ( name->hash == dhn->hash &&
for (dhn = dh->h[(unsigned) name->hash % AUTOFS_HASH_SIZE];
dhn;
dhn = dhn->next) {
if (name->hash == dhn->hash &&
name->len == dhn->len &&
!memcmp(name->name, dhn->name, name->len) )
!memcmp(name->name, dhn->name, name->len))
break;
}
@ -131,9 +142,9 @@ void autofs_hash_insert(struct autofs_dirhash *dh, struct autofs_dir_ent *ent)
struct autofs_dir_ent **dhnp;
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)
dget(ent->dentry);
@ -141,19 +152,19 @@ void autofs_hash_insert(struct autofs_dirhash *dh, struct autofs_dir_ent *ent)
ent->next = *dhnp;
ent->back = dhnp;
*dhnp = ent;
if ( ent->next )
if (ent->next)
ent->next->back = &(ent->next);
}
void autofs_hash_delete(struct autofs_dir_ent *ent)
{
*(ent->back) = ent->next;
if ( ent->next )
if (ent->next)
ent->next->back = ent->back;
autofs_delete_usage(ent);
if ( ent->dentry )
if (ent->dentry)
dput(ent->dentry);
kfree(ent->name);
kfree(ent);
@ -176,37 +187,37 @@ struct autofs_dir_ent *autofs_hash_enum(const struct autofs_dirhash *dh,
bucket = (*ptr >> 16) - 1;
ecount = *ptr & 0xffff;
if ( bucket < 0 ) {
if (bucket < 0)
bucket = ecount = 0;
}
DPRINTK(("autofs_hash_enum: bucket %d, entry %d\n", bucket, ecount));
ent = last ? last->next : NULL;
if ( ent ) {
if (ent) {
ecount++;
} else {
while ( bucket < AUTOFS_HASH_SIZE ) {
while (bucket < AUTOFS_HASH_SIZE) {
ent = dh->h[bucket];
for ( i = ecount ; ent && i ; i-- )
for (i = ecount ; ent && i ; i--)
ent = ent->next;
if (ent) {
ecount++; /* Point to *next* entry */
break;
}
bucket++; ecount = 0;
}
}
#ifdef DEBUG
if ( !ent )
printk("autofs_hash_enum: nothing found\n");
if (!ent)
printk(KERN_DEBUG "autofs_hash_enum: nothing found\n");
else {
printk("autofs_hash_enum: found hash %08x, name", ent->hash);
autofs_say(ent->name,ent->len);
printk(KERN_DEBUG "autofs_hash_enum: found hash %08x, name",
ent->hash);
autofs_say(ent->name, ent->len);
}
#endif
@ -221,9 +232,9 @@ void autofs_hash_dputall(struct autofs_dirhash *dh)
int i;
struct autofs_dir_ent *ent;
for ( i = 0 ; i < AUTOFS_HASH_SIZE ; i++ ) {
for ( ent = dh->h[i] ; ent ; ent = ent->next ) {
if ( ent->dentry ) {
for (i = 0 ; i < AUTOFS_HASH_SIZE ; i++) {
for (ent = dh->h[i] ; ent ; ent = ent->next) {
if (ent->dentry) {
dput(ent->dentry);
ent->dentry = NULL;
}
@ -238,10 +249,10 @@ void autofs_hash_nuke(struct autofs_sb_info *sbi)
int i;
struct autofs_dir_ent *ent, *nent;
for ( i = 0 ; i < AUTOFS_HASH_SIZE ; i++ ) {
for ( ent = sbi->dirhash.h[i] ; ent ; ent = nent ) {
for (i = 0 ; i < AUTOFS_HASH_SIZE ; i++) {
for (ent = sbi->dirhash.h[i] ; ent ; ent = nent) {
nent = ent->next;
if ( ent->dentry )
if (ent->dentry)
dput(ent->dentry);
kfree(ent->name);
kfree(ent);

View File

@ -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.

View File

@ -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

View File

@ -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>

View File

@ -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>

View File

@ -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));
}

View File

@ -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_ */

View File

@ -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;
}
}

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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,
};

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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);
}

View File

@ -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_ */

View File

@ -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

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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);
}

View File

@ -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

View File

@ -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_ */

View File

@ -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);
}

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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.

View File

@ -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.

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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));
}

View File

@ -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_ */

View File

@ -7,53 +7,6 @@
#define MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES 256
#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
{
USHORT Vcid;
@ -429,26 +382,28 @@ Driver adapter data structure
struct _MINI_ADAPTER
{
struct _MINI_ADAPTER *next;
PVOID pvOsDepData;
struct net_device *dev;
u32 msg_enable;
CHAR *caDsxReqResp;
atomic_t ApplicationRunning;
atomic_t ApplicationRunning;
volatile INT CtrlQueueLen;
atomic_t AppCtrlQueueLen;
BOOLEAN AppCtrlQueueOverFlow;
atomic_t CurrentApplicationCount;
atomic_t RegisteredApplicationCount;
BOOLEAN TimerActive;
ULONG StatisticsPointer;
atomic_t AppCtrlQueueLen;
BOOLEAN AppCtrlQueueOverFlow;
atomic_t CurrentApplicationCount;
atomic_t RegisteredApplicationCount;
BOOLEAN LinkUpStatus;
BOOLEAN TimerActive;
u32 StatisticsPointer;
struct sk_buff *RxControlHead;
struct sk_buff *RxControlTail;
// spinlock_t RxControlQueuelock;
struct semaphore RxAppControlQueuelock;
struct semaphore fw_download_sema;
PPER_TARANG_DATA pTarangs;
spinlock_t control_queue_lock;
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
// deserialized miniport support variables
@ -458,24 +413,15 @@ struct _MINI_ADAPTER
// this to keep track of the Tx and Rx MailBox Registers.
atomic_t CurrNumFreeTxDesc;
// to keep track the no of byte recieved
atomic_t RxRollOverCount;
USHORT PrevNumRecvDescs;
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;
PacketInfo PackInfo[NO_OF_QUEUES];
S_CLASSIFIER_RULE astClassifierTable[MAX_CLASSIFIERS];
BOOLEAN TransferMode;
/*************** qos ******************/
UINT bETHCSEnabled;
BOOLEAN bETHCSEnabled;
ULONG BEBucketSize;
ULONG rtPSBucketSize;
@ -483,7 +429,6 @@ struct _MINI_ADAPTER
BOOLEAN AutoLinkUp;
BOOLEAN AutoSyncup;
struct net_device *dev;
int major;
int minor;
wait_queue_head_t tx_packet_wait_queue;
@ -491,8 +436,6 @@ struct _MINI_ADAPTER
atomic_t process_waiting;
BOOLEAN fw_download_done;
unsigned int ctrlpkt_present;
BOOLEAN packets_given_to_all;
char *txctlpacket[MAX_CNTRL_PKTS];
atomic_t cntrlpktCnt ;
atomic_t index_app_read_cntrlpkt;
@ -502,34 +445,30 @@ struct _MINI_ADAPTER
struct semaphore rdmwrmsync;
STTARGETDSXBUFFER astTargetDsxBuffer[MAX_TARGET_DSX_BUFFERS];
ULONG ulFreeTargetBufferCnt;
ULONG ulFreeTargetBufferCnt;
ULONG ulCurrentTargetBuffer;
ULONG ulTotalTargetBuffersAvailable;
unsigned int timeout;
int irq;
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;
atomic_t bAbortedByHost;
BOOLEAN bBinDownloaded;
BOOLEAN bCfgDownloaded;
USHORT usBestEffortQueueIndex;
BOOLEAN bSyncUpRequestSent;
// struct semaphore data_packet_queue_lock;
BOOLEAN bFlashBoot;
BOOLEAN bBinDownloaded;
BOOLEAN bCfgDownloaded;
BOOLEAN bSyncUpRequestSent;
USHORT usBestEffortQueueIndex;
wait_queue_head_t ioctl_fw_dnld_wait_queue;
BOOLEAN waiting_to_fw_download_done;
pid_t fw_download_process_pid;
PSTARGETPARAMS pstargetparams;
BOOLEAN device_removed;
BOOLEAN DeviceAccess;
INT DDRSetting;
BOOLEAN bDDRInitDone;
ULONG ulPowerSaveMode;
BOOLEAN bIsAutoCorrectEnabled;
BOOLEAN bDDRInitDone;
INT DDRSetting;
ULONG ulPowerSaveMode;
spinlock_t txtransmitlock;
B_UINT8 txtransmit_running;
/* Thread for control packet handling */
@ -567,13 +506,13 @@ struct _MINI_ADAPTER
unsigned int usIdleModePattern;
//BOOLEAN bTriedToWakeUpFromShutdown;
BOOLEAN bLinkDownRequested;
unsigned int check_for_hang;
int downloadDDR;
PHS_DEVICE_EXTENSION stBCMPhsContext;
S_HDR_SUPRESSION_CONTEXTINFO stPhsTxContextInfo;
uint8_t ucaPHSPktRestoreBuf[2048];
uint8_t bPHSEnabled;
int AutoFirmDld;
BOOLEAN AutoFirmDld;
BOOLEAN bMipsConfig;
BOOLEAN bDPLLConfig;
UINT32 aTxPktSizeHist[MIBS_MAX_HIST_ENTRIES];
@ -599,10 +538,9 @@ struct _MINI_ADAPTER
struct semaphore NVMRdmWrmLock;
BOOLEAN bNetworkInterfaceRegistered;
BOOLEAN bNetdeviceNotifierRegistered;
struct device *pstCreatedClassDevice;
BOOLEAN bUsbClassDriverRegistered;
// BOOLEAN InterfaceUpStatus;
PFLASH2X_CS_INFO psFlash2xCSInfo;
PFLASH_CS_INFO psFlashCSInfo ;
@ -630,17 +568,13 @@ struct _MINI_ADAPTER
struct semaphore LowPowerModeSync;
ULONG liDrainCalculated;
UINT gpioBitMap;
S_BCM_DEBUG_STATE stDebugState;
};
typedef struct _MINI_ADAPTER MINI_ADAPTER, *PMINI_ADAPTER;
typedef struct _DEVICE_EXTENSION
{
PMINI_ADAPTER pAdapt;
}DEVICE_EXTENSION,*PDEVICE_EXTENSION;
#define GET_BCM_ADAPTER(net_dev) netdev_priv(net_dev)
struct _ETH_HEADER_STRUC {
UCHAR au8DestinationAddress[6];
@ -667,8 +601,8 @@ typedef LINK_REQUEST CONTROL_MESSAGE;
typedef struct _DDR_SETTING
{
ULONG ulRegAddress;
ULONG ulRegValue;
UINT ulRegAddress;
UINT ulRegValue;
}DDR_SETTING, *PDDR_SETTING;
typedef DDR_SETTING DDR_SET_NODE, *PDDR_SET_NODE;
INT

View File

@ -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

View File

@ -1,264 +1,238 @@
#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;
/***************************************************************************************/
/* proto-type of lower function */
#ifdef BCM_SHM_INTERFACE
const char *bcmVirtDeviceName="bcmeth";
#endif
static INT bcm_open(struct net_device *dev)
{
PMINI_ADAPTER Adapter = NULL ; //(PMINI_ADAPTER)dev->priv;
Adapter = GET_BCM_ADAPTER(dev);
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "======>");
if(Adapter->fw_download_done==FALSE)
return -EINVAL;
Adapter->if_up=1;
if(Adapter->LinkUpStatus == 1){
if(netif_queue_stopped(Adapter->dev)){
netif_carrier_on(Adapter->dev);
netif_start_queue(Adapter->dev);
}
PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev);
if (Adapter->fw_download_done == FALSE) {
pr_notice(PFX "%s: link up failed (download in progress)\n",
dev->name);
return -EBUSY;
}
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "<======");
return 0;
}
if (netif_msg_ifup(Adapter))
pr_info(PFX "%s: enabling interface\n", dev->name);
static INT bcm_close(struct net_device *dev)
{
PMINI_ADAPTER Adapter = NULL ;//gpadapter ;
Adapter = GET_BCM_ADAPTER(dev);
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "=====>");
Adapter->if_up=0;
if(!netif_queue_stopped(dev)) {
netif_carrier_off(dev);
netif_stop_queue(dev);
if (Adapter->LinkUpStatus) {
if (netif_msg_link(Adapter))
pr_info(PFX "%s: link up\n", dev->name);
netif_carrier_on(Adapter->dev);
netif_start_queue(Adapter->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;
}
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");
if(Adapter->dev && !IS_ERR(Adapter->dev) && Adapter->bNetworkInterfaceRegistered)
unregister_netdev(Adapter->dev);
/* Unregister the notifier block */
if(Adapter->bNetdeviceNotifierRegistered == TRUE)
{
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Unregistering netdevice notifier\n");
unregister_netdevice_notifier(&bcm_notifier_block);
}
PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev);
if (netif_msg_ifdown(Adapter))
pr_info(PFX "%s: disabling interface\n", dev->name);
netif_carrier_off(dev);
netif_stop_queue(dev);
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;
result = InterfaceInitialize();
if(result)
{
printk("Initialisation failed for usbbcm");
net->netdev_ops = &bcmNetDevOps;
net->ethtool_ops = &bcm_ethtool_ops;
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
{
printk("Initialised usbbcm");
}
return result;
result = register_netdev(net);
if (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;
}
static void bcm_exit(void)
void unregister_networkdev(PMINI_ADAPTER Adapter)
{
printk("%s %s Calling InterfaceExit\n",__FILE__, __FUNCTION__);
InterfaceExit();
printk("%s %s InterfaceExit returned\n",__FILE__, __FUNCTION__);
struct net_device *net = Adapter->dev;
PS_INTERFACE_ADAPTER IntfAdapter = Adapter->pvInterfaceAdapter;
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");

View File

@ -15,6 +15,7 @@ typedef enum _E_CLASSIFIER_ACTION
eDeleteClassifier
}E_CLASSIFIER_ACTION;
static ULONG GetNextTargetBufferLocation(PMINI_ADAPTER Adapter,B_UINT16 tid);
/************************************************************
* Function - SearchSfid
@ -28,7 +29,7 @@ typedef enum _E_CLASSIFIER_ACTION
* Returns - Queue index for this SFID(If 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;
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
* Else returns Invalid Index.
****************************************************************/
__inline INT SearchFreeSfid(PMINI_ADAPTER Adapter)
static INT SearchFreeSfid(PMINI_ADAPTER Adapter)
{
UINT uiIndex=0;
for(uiIndex=0; uiIndex < (NO_OF_QUEUES-1); uiIndex++)
if(Adapter->PackInfo[uiIndex].ulSFID==0)
return uiIndex;
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
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
*/
__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;
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.
@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;
@ -106,7 +97,7 @@ static __inline int SearchFreeClsid(PMINI_ADAPTER Adapter /**Adapter Context*/
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
flush_queue(Adapter,uiSearchRuleIndex);
@ -985,7 +976,7 @@ static VOID CopyToAdapter( register PMINI_ADAPTER Adapter, /**<Pointer to the A
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 = pstAddIndication;
@ -1061,12 +1052,6 @@ static VOID DumpCmControlPacket(PVOID pvBuffer)
pstAddIndication->sfAuthorizedSet.u32MaxTrafficBurst);
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MinReservedTrafficRate : 0x%X",
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",
pstAddIndication->sfAuthorizedSet.u8VendorSpecificQoSParamLength);
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);
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16UnsolicitedPollingInterval : 0x%X",
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 ",
*(unsigned int*)pstAddIndication->sfAuthorizedSet.u8HARQChannelMapping,
@ -1158,11 +1136,6 @@ static VOID DumpCmControlPacket(PVOID pvBuffer)
psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0],
psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1],
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++)
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);
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficPriority : 0x%02X",
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",
pstAddIndication->sfAdmittedSet.u32MaxTrafficBurst);
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);
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8PagingPreference : 0x%X",
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",
@ -1378,11 +1336,6 @@ static VOID DumpCmControlPacket(PVOID pvBuffer)
psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0],
psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1],
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++)
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Protocol: 0x%02X ",
psfCSType->cCPacketClassificationRule.u8Protocol);
@ -1497,20 +1450,10 @@ static VOID DumpCmControlPacket(PVOID pvBuffer)
pstAddIndication->sfActiveSet.u8QosParamSet);
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficPriority : 0x%02X",
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",
pstAddIndication->sfActiveSet.u32MaxTrafficBurst);
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MinReservedTrafficRate : 0x%X",
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",
pstAddIndication->sfActiveSet.u8VendorSpecificQoSParamLength);
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);
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8PagingPreference : 0x%X",
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",
@ -1597,11 +1533,6 @@ static VOID DumpCmControlPacket(PVOID pvBuffer)
psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0],
psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1],
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++)
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8Protocol : 0x%X ",
psfCSType->cCPacketClassificationRule.u8Protocol);
@ -1706,12 +1637,8 @@ static inline ULONG RestoreSFParam(PMINI_ADAPTER Adapter, ULONG ulAddrSFParamSet
return 0;
}
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
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "nBytesToRead = %x", nBytesToRead);
if(rdm(Adapter, ulAddrSFParamSet, (PUCHAR)pucDestBuffer, nBytesToRead) < 0)
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 uiRetVal =0;
int ret = 0;
if(ulAddrSFParamSet == 0 || NULL == pucSrcBuffer)
{
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);
uiRetVal = wrm(Adapter,ulAddrSFParamSet,(PUCHAR)pucSrcBuffer, nBytesToWrite);
if(uiRetVal < 0) {
ret = wrm(Adapter, ulAddrSFParamSet, (u8 *)pucSrcBuffer, nBytesToWrite);
if (ret < 0) {
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "%s:%d WRM failed",__FUNCTION__, __LINE__);
return uiRetVal;
return ret;
}
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!
pstAddIndication=(stLocalSFAddIndication *)kmalloc(sizeof(*pstAddIndication), GFP_KERNEL);
pstAddIndication=kmalloc(sizeof(*pstAddIndication), GFP_KERNEL);
if(NULL==pstAddIndication)
return 0;
@ -1844,7 +1768,7 @@ ULONG StoreCmControlResponseMessage(PMINI_ADAPTER Adapter,PVOID pvBuffer,UINT *p
(*puBufferLength) = sizeof(stLocalSFAddIndication);
*(stLocalSFAddIndication *)pvBuffer = *pstAddIndication;
bcm_kfree(pstAddIndication);
kfree(pstAddIndication);
return 1;
}
@ -1931,7 +1855,7 @@ static inline stLocalSFAddIndicationAlt
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "============================================================");
return pstAddIndicationDest;
failed_restore_sf_param:
bcm_kfree(pstAddIndicationDest);
kfree(pstAddIndicationDest);
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "<=====" );
return NULL;
}
@ -1988,7 +1912,7 @@ ULONG SetUpTargetDsxBuffers(PMINI_ADAPTER Adapter)
return 1;
}
ULONG GetNextTargetBufferLocation(PMINI_ADAPTER Adapter,B_UINT16 tid)
static ULONG GetNextTargetBufferLocation(PMINI_ADAPTER Adapter,B_UINT16 tid)
{
ULONG ulTargetDSXBufferAddress;
ULONG ulTargetDsxBufferIndexToUse,ulMaxTry;
@ -2049,7 +1973,7 @@ INT FreeAdapterDsxBuffer(PMINI_ADAPTER Adapter)
{
if(Adapter->caDsxReqResp)
{
bcm_kfree(Adapter->caDsxReqResp);
kfree(Adapter->caDsxReqResp);
}
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));
CopyBufferToControlPacket(Adapter,(PVOID)Adapter->caDsxReqResp);
bcm_kfree(pstAddIndication);
kfree(pstAddIndication);
}
break;
case DSA_RSP:
@ -2118,7 +2042,7 @@ BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter, /**<Pointer to the Adap
case DSA_ACK:
{
UINT uiSearchRuleIndex=0;
struct timeval tv = {0};
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "VCID:0x%X",
ntohs(pstAddIndication->u16VCID));
uiSearchRuleIndex=SearchFreeSfid(Adapter);
@ -2169,7 +2093,7 @@ BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter, /**<Pointer to the Adap
Adapter->PackInfo[uiSearchRuleIndex].bActive=FALSE;
Adapter->PackInfo[uiSearchRuleIndex].bValid=FALSE;
Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value=0;
bcm_kfree(pstAddIndication);
kfree(pstAddIndication);
}
else if(psfLocalSet->bValid && (pstAddIndication->u8CC == 0))
@ -2200,14 +2124,13 @@ BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter, /**<Pointer to the Adap
if(!Adapter->LinkUpStatus)
{
netif_carrier_on(Adapter->dev);
netif_start_queue(Adapter->dev);
netif_start_queue(Adapter->dev);
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);
wake_up(&Adapter->tx_packet_wait_queue);
Adapter->liTimeSinceLastNetEntry = tv.tv_sec;
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "============Tx Service Flow Created!");
Adapter->liTimeSinceLastNetEntry = get_seconds();
}
}
}
@ -2218,13 +2141,13 @@ BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter, /**<Pointer to the Adap
Adapter->PackInfo[uiSearchRuleIndex].bActive=FALSE;
Adapter->PackInfo[uiSearchRuleIndex].bValid=FALSE;
Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value=0;
bcm_kfree(pstAddIndication);
kfree(pstAddIndication);
}
}
else
{
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0, "DSA ACK did not get valid SFID");
bcm_kfree(pstAddIndication);
kfree(pstAddIndication);
return FALSE;
}
}
@ -2239,7 +2162,7 @@ BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter, /**<Pointer to the Adap
((stLocalSFChangeIndicationAlt*)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSC_RSP;
CopyBufferToControlPacket(Adapter,(PVOID)Adapter->caDsxReqResp);
bcm_kfree(pstAddIndication);
kfree(pstAddIndication);
}
break;
case DSC_RSP:
@ -2312,13 +2235,13 @@ BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter, /**<Pointer to the Adap
else if(pstChangeIndication->u8CC == 6)
{
deleteSFBySfid(Adapter,uiSearchRuleIndex);
bcm_kfree(pstAddIndication);
kfree(pstAddIndication);
}
}
else
{
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0, "DSC ACK did not get valid SFID");
bcm_kfree(pstAddIndication);
kfree(pstAddIndication);
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");
break;
default:
bcm_kfree(pstAddIndication);
kfree(pstAddIndication);
return FALSE ;
}
return TRUE;

View File

@ -150,8 +150,6 @@ typedef struct stLocalSFChangeIndicationAlt{
ULONG StoreCmControlResponseMessage(PMINI_ADAPTER Adapter,PVOID pvBuffer,UINT *puBufferLength);
ULONG GetNextTargetBufferLocation(PMINI_ADAPTER Adapter,B_UINT16 tid);
INT AllocAdapterDsxBuffer(PMINI_ADAPTER Adapter);
INT FreeAdapterDsxBuffer(PMINI_ADAPTER Adapter);
@ -159,7 +157,6 @@ ULONG SetUpTargetDsxBuffers(PMINI_ADAPTER Adapter);
BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter,PVOID pvBuffer);
VOID deleteSFBySfid(PMINI_ADAPTER Adapter, UINT uiSearchRuleIndex);
#pragma pack (pop)

View File

@ -1,6 +1,5 @@
#include "headers.h"
#ifndef BCM_SHM_INTERFACE
#define DDR_DUMP_INTERNAL_DEVICE_MEMORY 0xBFC02B00
@ -188,17 +187,6 @@ static DDR_SET_NODE asDPLL_266MHZ[] = {
{0x0f000840,0x0FFF1B00},
{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
static DDR_SET_NODE asT3B_DDRSetting133MHz[] = {// # DPLL Clock Setting
@ -788,7 +776,7 @@ int ddr_init(MINI_ADAPTER *Adapter)
{
PDDR_SETTING psDDRSetting=NULL;
ULONG RegCount=0;
ULONG value = 0;
UINT value = 0;
UINT uiResetValue = 0;
UINT uiClockSetting = 0;
int retval = STATUS_SUCCESS;
@ -982,7 +970,7 @@ int ddr_init(MINI_ADAPTER *Adapter)
{
value = psDDRSetting->ulRegValue;
}
retval = wrmalt(Adapter, psDDRSetting->ulRegAddress, (PUINT)&value, sizeof(value));
retval = wrmalt(Adapter, psDDRSetting->ulRegAddress, &value, sizeof(value));
if(STATUS_SUCCESS != retval) {
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"%s:%d\n", __FUNCTION__, __LINE__);
break;
@ -1298,5 +1286,4 @@ int download_ddr_settings(PMINI_ADAPTER Adapter)
return retval;
}
#endif

View File

@ -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;
}

View File

@ -9,34 +9,6 @@
#include <linux/string.h>
#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.
#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 { \
if ((DBG_TYPE_PRINTK == Type) && (PRINTKS_ON)) { \
printk ("%s:" string, __FUNCTION__, ##args); \
printk("\n"); \
} else if (!Adapter) \
; \
else { \
if (((dbg_level & DBG_LVL_BITMASK) <= Adapter->stDebugState.debug_level) && \
((Type & Adapter->stDebugState.type) && (SubType & Adapter->stDebugState.subtype[Type]))) { \
if (dbg_level & DBG_NO_FUNC_PRINT) \
printk (string, ##args); \
else \
{ \
printk ("%s:" string, __FUNCTION__, ##args); \
printk("\n"); \
} \
} \
} \
} while (0)
#define BCM_DEBUG_PRINT(Adapter, Type, SubType, dbg_level, string, args...) \
do { \
if (DBG_TYPE_PRINTK == Type) \
pr_info("%s:" string, __func__, ##args); \
else if (Adapter && \
(dbg_level & DBG_LVL_BITMASK) <= Adapter->stDebugState.debug_level && \
(Type & Adapter->stDebugState.type) && \
(SubType & Adapter->stDebugState.subtype[Type])) { \
if (dbg_level & DBG_NO_FUNC_PRINT) \
printk(KERN_DEBUG string, ##args); \
else \
printk(KERN_DEBUG "%s:" string, __func__, ##args); \
} \
} while (0)
#define BCM_DEBUG_PRINT_BUFFER(Adapter, Type, SubType, dbg_level, buffer, bufferlen) do { \
if ((DBG_TYPE_PRINTK == Type) && (PRINTKS_ON)) { \
bcm_print_buffer( dbg_level, __FUNCTION__, __FILE__, __LINE__, buffer, bufferlen, BCM_BASE_TYPE_HEX); \
} else if (!Adapter) \
; \
else { \
if (((dbg_level & DBG_LVL_BITMASK) <= Adapter->stDebugState.debug_level) && \
((Type & Adapter->stDebugState.type) && (SubType & Adapter->stDebugState.subtype[Type]))) { \
if (dbg_level & DBG_NO_FUNC_PRINT) \
bcm_print_buffer( dbg_level, NULL, NULL, __LINE__, buffer, bufferlen, BCM_BASE_TYPE_HEX); \
else \
bcm_print_buffer( dbg_level, __FUNCTION__, __FILE__, __LINE__, buffer, bufferlen, BCM_BASE_TYPE_HEX); \
} \
} \
} while (0)
if (DBG_TYPE_PRINTK == Type || \
(Adapter && \
(dbg_level & DBG_LVL_BITMASK) <= Adapter->stDebugState.debug_level && \
(Type & Adapter->stDebugState.type) && \
(SubType & Adapter->stDebugState.subtype[Type]))) { \
printk(KERN_DEBUG "%s:\n", __func__); \
print_hex_dump(KERN_DEBUG, " ", DUMP_PREFIX_OFFSET, \
16, 1, buffer, bufferlen, false); \
} \
} while(0)
#define BCM_SHOW_DEBUG_BITMAP(Adapter) do { \

View File

@ -11,8 +11,7 @@ When a control packet is received, analyze the
Enqueue the control packet for Application.
@return None
*/
VOID handle_rx_control_packet(PMINI_ADAPTER Adapter, /**<Pointer to the Adapter structure*/
struct sk_buff *skb) /**<Pointer to the socket buffer*/
static VOID handle_rx_control_packet(PMINI_ADAPTER Adapter, struct sk_buff *skb)
{
PPER_TARANG_DATA pTarang = NULL;
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;
BOOLEAN drop_pkt_flag = TRUE ;
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)
{
@ -134,7 +135,7 @@ VOID handle_rx_control_packet(PMINI_ADAPTER Adapter, /**<Pointer to the Adapter
}
up(&Adapter->RxAppControlQueuelock);
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");
}
@ -185,33 +186,7 @@ int control_packet_handler (PMINI_ADAPTER Adapter /**< pointer to adapter obje
{
DEQUEUEPACKET(Adapter->RxControlHead,Adapter->RxControlTail);
// 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);
handle_rx_control_packet(Adapter, ctrl_packet);
@ -234,7 +209,7 @@ INT flushAllAppQ(void)
{
PacketToDrop=pTarang->RxAppControlHead;
DEQUEUEPACKET(pTarang->RxAppControlHead,pTarang->RxAppControlTail);
bcm_kfree_skb(PacketToDrop);
dev_kfree_skb(PacketToDrop);
}
pTarang->AppCtrlQueueLen = 0;
//dropped contrl packet statistics also should be reset.

View File

@ -1,7 +0,0 @@
#ifndef _HOST_MIBS_H
#define _HOST_MIBS_H
INT ProcessGetHostMibs(PMINI_ADAPTER Adapter,
PVOID ioBuffer,
ULONG inputBufferLength);
#endif

View File

@ -1,5 +1,9 @@
#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)
{
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 uiIpv6AddIndex=0;
@ -310,7 +314,7 @@ BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pst
return FALSE;
}
BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header)
static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header)
{
UINT uiLoopIndex=0;
UINT uiIpv6AddIndex=0;
@ -376,7 +380,7 @@ VOID DumpIpv6Address(ULONG *puIpv6Address)
}
VOID DumpIpv6Header(IPV6Header *pstIpv6Header)
static VOID DumpIpv6Header(IPV6Header *pstIpv6Header)
{
UCHAR ucVersion;
UCHAR ucPrio ;

View File

@ -101,15 +101,12 @@ typedef enum _E_IPADDR_CONTEXT
//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 */
PVOID pcIpHeader, /**<Pointer to the IP Hdr of the packet*/
S_CLASSIFIER_RULE *pstClassifierRule );
VOID DumpIpv6Address(ULONG *puIpv6Address);
VOID DumpIpv6Header(IPV6Header *pstIpv6Header);
extern BOOLEAN MatchSrcPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushSrcPort);
extern BOOLEAN MatchDestPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushSrcPort);

View File

@ -1,20 +1,18 @@
#include "headers.h"
#ifndef BCM_SHM_INTERFACE
int InterfaceFileDownload( PVOID arg,
struct file *flp,
unsigned int on_chip_loc)
{
char *buff=NULL;
// unsigned int reg=0;
mm_segment_t oldfs={0};
int errno=0, len=0 /*,is_config_file = 0*/;
loff_t pos=0;
PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg;
//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)
{
return -ENOMEM;
@ -49,7 +47,7 @@ int InterfaceFileDownload( PVOID arg,
on_chip_loc+=MAX_TRANSFER_CTRL_BYTE_USB;
}/* End of for(;;)*/
bcm_kfree(buff);
kfree(buff);
return errno;
}
@ -57,7 +55,7 @@ int InterfaceFileReadbackFromChip( PVOID arg,
struct file *flp,
unsigned int on_chip_loc)
{
char *buff=NULL, *buff_readback=NULL;
char *buff, *buff_readback;
unsigned int reg=0;
mm_segment_t oldfs={0};
int errno=0, len=0, is_config_file = 0;
@ -66,12 +64,12 @@ int InterfaceFileReadbackFromChip( PVOID arg,
INT Status = STATUS_SUCCESS;
PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg;
buff=(PCHAR)kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_DMA);
buff_readback=(PCHAR)kmalloc(MAX_TRANSFER_CTRL_BYTE_USB , GFP_DMA);
buff=kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_DMA);
buff_readback=kmalloc(MAX_TRANSFER_CTRL_BYTE_USB , GFP_DMA);
if(!buff || !buff_readback)
{
bcm_kfree(buff);
bcm_kfree(buff_readback);
kfree(buff);
kfree(buff_readback);
return -ENOMEM;
}
@ -138,8 +136,8 @@ int InterfaceFileReadbackFromChip( PVOID arg,
on_chip_loc+=MAX_TRANSFER_CTRL_BYTE_USB;
}/* End of while(1)*/
exit:
bcm_kfree(buff);
bcm_kfree(buff_readback);
kfree(buff);
kfree(buff_readback);
return Status;
}
@ -165,7 +163,7 @@ static int bcm_download_config_file(PMINI_ADAPTER Adapter,
psFwInfo->pvMappedFirmwareAddress, psFwInfo->u32FirmwareLength);
if(retval)
{
bcm_kfree (Adapter->pstargetparams);
kfree(Adapter->pstargetparams);
Adapter->pstargetparams = NULL;
return -EFAULT;
}
@ -231,41 +229,6 @@ static int bcm_download_config_file(PMINI_ADAPTER Adapter,
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,
unsigned char *buff,unsigned int len)
{
@ -297,58 +260,6 @@ static int bcm_compare_buff_contents(unsigned char *readbackbuff,
}
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 retval = STATUS_SUCCESS;
@ -375,7 +286,7 @@ int bcm_ioctl_fw_download(PMINI_ADAPTER Adapter, FIRMWARE_INFO *psFwInfo)
else
{
buff = (PUCHAR)kzalloc(psFwInfo->u32FirmwareLength,GFP_KERNEL);
buff = kzalloc(psFwInfo->u32FirmwareLength,GFP_KERNEL);
if(buff==NULL)
{
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 ;
}
#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,
buff,
psFwInfo->u32FirmwareLength,
@ -417,7 +311,7 @@ int bcm_ioctl_fw_download(PMINI_ADAPTER Adapter, FIRMWARE_INFO *psFwInfo)
}
}
error:
bcm_kfree(buff);
kfree(buff);
return retval;
}
@ -450,11 +344,10 @@ static INT buffRdbkVerify(PMINI_ADAPTER Adapter,
PUCHAR mappedbuffer, UINT u32FirmwareLength,
ULONG u32StartingAddress)
{
PUCHAR readbackbuff = NULL;
UINT len = u32FirmwareLength;
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)
{
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;
mappedbuffer +=len;
}/* end of while (u32FirmwareLength && !retval) */
bcm_kfree(readbackbuff);
kfree(readbackbuff);
return retval;
}
@ -506,5 +399,4 @@ error:
return status;
}
#endif

View File

@ -98,14 +98,6 @@ int InterfaceIdleModeRespond(PMINI_ADAPTER Adapter, unsigned int* puiBuffer)
Adapter->bTriedToWakeUpFromlowPowerMode = FALSE;
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
@ -154,17 +146,7 @@ int InterfaceIdleModeRespond(PMINI_ADAPTER Adapter, unsigned int* puiBuffer)
return status;
}
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)
static int InterfaceAbortIdlemode(PMINI_ADAPTER Adapter, unsigned int Pattern)
{
int status = STATUS_SUCCESS;
unsigned int value;

View File

@ -7,8 +7,6 @@ INT InterfaceIdleModeRespond(PMINI_ADAPTER Adapter, unsigned int *puiBuffer);
VOID InterfaceWriteIdleModeWakePattern(PMINI_ADAPTER Adapter);
INT InterfaceAbortIdlemode(PMINI_ADAPTER Adapter, unsigned int Pattern);
INT InterfaceWakeUp(PMINI_ADAPTER Adapter);
VOID InterfaceHandleShutdownModeWakeup(PMINI_ADAPTER Adapter);

File diff suppressed because it is too large Load Diff

View File

@ -8,9 +8,11 @@
#define BCM_USB_PRODUCT_ID_T3 0x0300
#define BCM_USB_PRODUCT_ID_T3B 0x0210
#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_1901 0xe017
#define BCM_USB_PRODUCT_ID_226 0x0132
#define BCM_USB_PRODUCT_ID_ZTE_TU25 0x0007
#define BCM_USB_MINOR_BASE 192
@ -19,33 +21,7 @@ INT InterfaceInitialize(void);
INT InterfaceExit(void);
#ifndef BCM_SHM_INTERFACE
INT InterfaceAdapterInit(PS_INTERFACE_ADAPTER Adapter);
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

View File

@ -1,6 +1,5 @@
#include "headers.h"
#ifndef BCM_SHM_INTERFACE
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;
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)
{
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");
Adapter->bEndPointHalted = TRUE ;
wake_up(&Adapter->tx_packet_wait_queue);
urb->status = STATUS_SUCCESS ;;
urb->status = STATUS_SUCCESS ;
return;
}
/* software-driven interface shutdown */
@ -164,40 +167,3 @@ INT StartInterruptUrb(PS_INTERFACE_ADAPTER psIntfAdapter)
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

View File

@ -1,17 +1,5 @@
#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
InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter,
UINT addr,
@ -102,7 +90,7 @@ InterfaceWRM(PS_INTERFACE_ADAPTER psIntfAdapter,
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...");
return EACCES;
return -EACCES;
}
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 */
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;
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++)
{
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->uCurrTcb, 0);
atomic_set(&psIntfAdapter->uNumRcbUsed, 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)
@ -282,9 +260,6 @@ VOID putUsbSuspend(struct work_struct *work)
if(psIntfAdapter->bSuspended == FALSE)
usb_autopm_put_interface(intf);
else
BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Interface Resumed Completely\n");
}
#endif

View File

@ -1,9 +1,6 @@
#ifndef __INTERFACE_MISC_H
#define __INTERFACE_MISC_H
PS_INTERFACE_ADAPTER
InterfaceAdapterGet(PMINI_ADAPTER psAdapter);
INT
InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter,
UINT addr,

View File

@ -1,5 +1,15 @@
#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
@ -38,13 +48,9 @@ static void read_bulk_callback(struct urb *urb)
PMINI_ADAPTER Adapter = psIntfAdapter->psAdapter;
PLEADER pLeader = urb->transfer_buffer;
#if 0
int *puiBuffer = NULL;
struct timeval tv;
memset(&tv, 0, sizeof(tv));
do_gettimeofday(&tv);
#endif
if (unlikely(netif_msg_rx_status(Adapter)))
pr_info(PFX "%s: rx urb status %d length %d\n",
Adapter->dev->name, urb->status, urb->actual_length);
if((Adapter->device_removed == TRUE) ||
(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);
if(MAX_CNTL_PKT_SIZE < pLeader->PLength)
{
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Corrupted leader length...%d\n",
pLeader->PLength);
atomic_inc(&Adapter->RxPacketDroppedCount);
atomic_add(pLeader->PLength, &Adapter->BadRxByteCount);
if (netif_msg_rx_err(Adapter))
pr_info(PFX "%s: corrupted leader length...%d\n",
Adapter->dev->name, pLeader->PLength);
++Adapter->dev->stats.rx_dropped;
atomic_dec(&psIntfAdapter->uNumRcbUsed);
return;
}
@ -145,10 +151,9 @@ static void read_bulk_callback(struct urb *urb)
skb_put (skb, pLeader->PLength + ETH_HLEN);
Adapter->PackInfo[QueueIndex].uiTotalRxBytes+=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);
if(Adapter->if_up)
if(netif_running(Adapter->dev))
{
/* Moving ahead by ETH_HLEN to the data ptr as received from FW */
skb_pull(skb, ETH_HLEN);
@ -173,9 +178,12 @@ static void read_bulk_callback(struct urb *urb)
else
{
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++)
{
if((pLeader->PLength <= MIBS_PKTSIZEHIST_RANGE*(uiIndex+1))

View File

@ -1,50 +1,5 @@
#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)*/
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 ;
BOOLEAN bpowerDownMsg = FALSE ;
PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
#if 0
struct timeval tv;
UINT time_ms = 0;
#endif
if (unlikely(netif_msg_tx_done(Adapter)))
pr_info(PFX "%s: transmit status %d\n", Adapter->dev->name, urb->status);
if(urb->status != STATUS_SUCCESS)
{
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 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) &&
(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 :
#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,
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;
UINT index = 0;
@ -183,20 +128,14 @@ static __inline PUSB_TCB GetBulkOutTcb(PS_INTERFACE_ADAPTER psIntfAdapter)
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;
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,
GFP_ATOMIC, &urb->transfer_dma);
#endif
if (!urb->transfer_buffer)
{
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);
}
#endif

View File

@ -3,11 +3,5 @@
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

View File

@ -1,10 +0,0 @@
#ifndef _MAIN_
#define _MAIN_
#if 0
typedef struct _MINI_ADAPTER
{
S_INTERFACE_ADAPTER stInterfaceAdapter;
}MINI_ADAPTER,*PMINI_ADAPTER;
#endif
#endif

View File

@ -75,14 +75,14 @@ static VOID UpdateTokenCount(register PMINI_ADAPTER Adapter)
* 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 ===>");
/* Validate the parameters */
if(NULL == Adapter || (psSF < Adapter->PackInfo &&
(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;
}
@ -94,51 +94,27 @@ static __inline ULONG GetSFTokenCount(PMINI_ADAPTER Adapter, PacketInfo *psSF)
}
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->uiPendedLast = 1;
}
}
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 <===");
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
This function despatches packet from the specified queue.
@return Zero(success) or Negative value(failure)
*/
static __inline INT SendPacketFromQueue(PMINI_ADAPTER Adapter,/**<Logical Adapter*/
PacketInfo *psSF, /**<Queue identifier*/
struct sk_buff* Packet) /**<Pointer to the packet to be sent*/
static INT SendPacketFromQueue(PMINI_ADAPTER Adapter,/**<Logical Adapter*/
PacketInfo *psSF, /**<Queue identifier*/
struct sk_buff* Packet) /**<Pointer to the packet to be sent*/
{
INT Status=STATUS_FAILURE;
UINT uiIndex =0,PktLen = 0;
@ -180,8 +156,7 @@ static __inline INT SendPacketFromQueue(PMINI_ADAPTER Adapter,/**<Logical Adapte
* Returns - None.
*
****************************************************************************/
static __inline VOID CheckAndSendPacketFromIndex
(PMINI_ADAPTER Adapter, PacketInfo *psSF)
static VOID CheckAndSendPacketFromIndex(PMINI_ADAPTER Adapter, PacketInfo *psSF)
{
struct sk_buff *QueuePacket=NULL;
char *pControlPacket = NULL;
@ -189,7 +164,7 @@ static __inline VOID CheckAndSendPacketFromIndex
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->ucDirection )
@ -197,10 +172,8 @@ static __inline VOID CheckAndSendPacketFromIndex
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "UpdateTokenCount ");
if(Adapter->IdleMode || Adapter->bPreparingForLowPowerMode)
{
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Device is in Idle Mode..Hence blocking Data Packets..\n");
return;
}
return; /* in idle mode */
// Check for Free Descriptors
if(atomic_read(&Adapter->CurrNumFreeTxDesc) <= MINIMUM_PENDING_DESCRIPTORS)
{
@ -208,9 +181,6 @@ static __inline VOID CheckAndSendPacketFromIndex
return ;
}
#if 0
PruneQueue(Adapter,(psSF-Adapter->PackInfo));
#endif
spin_lock_bh(&psSF->SFQueueLock);
QueuePacket=psSF->FirstTxQueue;
@ -240,7 +210,7 @@ static __inline VOID CheckAndSendPacketFromIndex
}
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",
psSF->uiCurrentTokenCount, iPacketLen);
//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 )
break ;
}/* 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);
Adapter->txtransmit_running = 0;
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "<======");

View File

@ -4,10 +4,6 @@
#ifndef __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 MAX_CLASSIFIERS 100
//#define MAX_CLASSIFIERS_PER_SF 20
@ -17,10 +13,9 @@
#define MAX_DATA_PKTS 200
#define MAX_ETH_SIZE 1536
#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 TX_QLEN 5
#define MAC_ADDR_REGISTER 0xbf60d000
@ -266,7 +261,7 @@ typedef enum _E_PHS_DSC_ACTION
#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 DDR_80_MHZ 0
@ -300,12 +295,7 @@ typedef enum _E_PHS_DSC_ACTION
/* Idle Mode Related Registers */
#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
#endif
#define SW_ABORT_IDLEMODE_PATTERN 0xd0ea1d1e
#define DEVICE_INT_OUT_EP_REG0 0x0F011870
@ -355,12 +345,7 @@ typedef enum ePMU_MODES
HYBRID_MODE_6 = 2
}PMU_MODE;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)
#define MAX_RDM_WRM_RETIRES 16
#else
#define MAX_RDM_WRM_RETIRES 1
#endif
enum eAbortPattern {
ABORT_SHUTDOWN_MODE = 1,
@ -369,27 +354,6 @@ enum eAbortPattern {
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 */
#define SKB_CB_CLASSIFICATION_OFFSET 0

View File

@ -6,7 +6,7 @@ obj-$(CONFIG_BCM_WIMAX) += bcm_wimax.o
bcm_wimax-y := InterfaceDld.o InterfaceIdleMode.o InterfaceInit.o InterfaceRx.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\
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

View File

@ -1,5 +1,12 @@
#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)
{
@ -60,21 +67,11 @@ InitAdapter(PMINI_ADAPTER psAdapter)
//init_waitqueue_head(&psAdapter->device_wake_queue);
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);
for (i=0;i<MAX_CNTRL_PKTS;i++)
{
psAdapter->txctlpacket[i] = (char *)kmalloc(MAX_CNTL_PKT_SIZE,
GFP_KERNEL);
psAdapter->txctlpacket[i] = kmalloc(MAX_CNTL_PKT_SIZE, GFP_KERNEL);
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);
@ -117,7 +114,7 @@ InitAdapter(PMINI_ADAPTER psAdapter)
VOID AdapterFree(PMINI_ADAPTER Adapter)
{
INT count = 0;
int count;
beceem_protocol_reset(Adapter);
@ -125,72 +122,66 @@ VOID AdapterFree(PMINI_ADAPTER Adapter)
if(Adapter->control_packet_handler && !IS_ERR(Adapter->control_packet_handler))
kthread_stop (Adapter->control_packet_handler);
if(Adapter->transmit_packet_thread && !IS_ERR(Adapter->transmit_packet_thread))
kthread_stop (Adapter->transmit_packet_thread);
wake_up(&Adapter->process_read_wait_queue);
kthread_stop (Adapter->transmit_packet_thread);
wake_up(&Adapter->process_read_wait_queue);
if(Adapter->LEDInfo.led_thread_running & (BCM_LED_THREAD_RUNNING_ACTIVELY | BCM_LED_THREAD_RUNNING_INACTIVELY))
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))
{
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);
}
unregister_control_device_interface(Adapter);
if(Adapter->dev && !IS_ERR(Adapter->dev))
free_netdev(Adapter->dev);
if(Adapter->pstargetparams != NULL)
{
bcm_kfree(Adapter->pstargetparams);
}
kfree(Adapter->pstargetparams);
for (count =0;count < MAX_CNTRL_PKTS;count++)
{
if(Adapter->txctlpacket[count])
bcm_kfree(Adapter->txctlpacket[count]);
}
kfree(Adapter->txctlpacket[count]);
FreeAdapterDsxBuffer(Adapter);
if(Adapter->pvOsDepData)
bcm_kfree (Adapter->pvOsDepData);
if(Adapter->pvInterfaceAdapter)
bcm_kfree(Adapter->pvInterfaceAdapter);
kfree(Adapter->pvInterfaceAdapter);
//Free the PHS Interface
PhsCleanup(&Adapter->stBCMPhsContext);
#ifndef BCM_SHM_INTERFACE
BcmDeAllocFlashCSStructure(Adapter);
#endif
bcm_kfree (Adapter);
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "<========\n");
free_netdev(Adapter->dev);
}
int create_worker_threads(PMINI_ADAPTER psAdapter)
static 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
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))
{
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);
}
// Tx Thread
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))
{
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);
return PTR_ERR(psAdapter->transmit_packet_thread);
}
return 0;
}
static inline struct file *open_firmware_file(PMINI_ADAPTER Adapter, char *path)
static struct file *open_firmware_file(PMINI_ADAPTER Adapter, const char *path)
{
struct file *flp=NULL;
mm_segment_t oldfs;
@ -200,26 +191,20 @@ static inline struct file *open_firmware_file(PMINI_ADAPTER Adapter, char *path)
set_fs(oldfs);
if(IS_ERR(flp))
{
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Unable To Open File %s, err %lx",
path, PTR_ERR(flp));
flp = NULL;
pr_err(DRV_NAME "Unable To Open File %s, err %ld",
path, PTR_ERR(flp));
flp = NULL;
}
else
{
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Got file descriptor pointer of %s!",
path);
}
if(Adapter->device_removed)
{
flp = NULL;
}
if(Adapter->device_removed)
flp = NULL;
return flp;
}
int BcmFileDownload(PMINI_ADAPTER Adapter,/**< Logical Adapter */
char *path, /**< path to image file */
static int BcmFileDownload(PMINI_ADAPTER Adapter,/**< Logical Adapter */
const char *path, /**< path to image file */
unsigned int loc /**< Download Address on the chip*/
)
{
@ -248,9 +233,7 @@ int BcmFileDownload(PMINI_ADAPTER Adapter,/**< Logical Adapter */
goto exit_download;
}
oldfs=get_fs();set_fs(get_ds());
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
vfs_llseek(flp, 0, 0);
#endif
set_fs(oldfs);
if(Adapter->bcm_file_readback_from_chip(Adapter->pvInterfaceAdapter,
flp, loc))
@ -265,31 +248,10 @@ exit_download:
if(flp && !(IS_ERR(flp)))
filp_close(flp, current->files);
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;
}
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
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
the wake up from idlemode is from host*/
//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;
wake_up(&Adapter->process_rx_cntrlpkt);
@ -489,9 +444,6 @@ INT CopyBufferToControlPacket(PMINI_ADAPTER Adapter,/**<Logical Adapter*/
atomic_inc(&Adapter->index_wr_txcntrlpkt);
BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "Calling transmit_packets");
atomic_set(&Adapter->TxPktAvail, 1);
#ifdef BCM_SHM_INTERFACE
virtual_mail_box_interrupt();
#endif
wake_up(&Adapter->tx_packet_wait_queue);
}
else
@ -530,18 +482,6 @@ static VOID SendStatisticsPointerRequest(PMINI_ADAPTER Adapter,
#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()
*
@ -552,7 +492,7 @@ void SendLinkDown(PMINI_ADAPTER Adapter)
*
* Returns - None.
*******************************************************************/
__inline VOID LinkMessage(PMINI_ADAPTER Adapter)
VOID LinkMessage(PMINI_ADAPTER Adapter)
{
PLINK_REQUEST pstLinkRequest=NULL;
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");
CopyBufferToControlPacket(Adapter, pstLinkRequest);
bcm_kfree(pstLinkRequest);
kfree(pstLinkRequest);
}
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "LinkMessage <=====");
return;
@ -614,8 +554,8 @@ __inline VOID LinkMessage(PMINI_ADAPTER Adapter)
VOID StatisticsResponse(PMINI_ADAPTER Adapter,PVOID pvBuffer)
{
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "%s====>",__FUNCTION__);
Adapter->StatisticsPointer = ntohl(*(PULONG)pvBuffer);
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Stats at %lx", Adapter->StatisticsPointer);
Adapter->StatisticsPointer = ntohl(*(__be32 *)pvBuffer);
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__);
return;
}
@ -764,7 +704,7 @@ void SendIdleModeResponse(PMINI_ADAPTER Adapter)
/* Wake the LED Thread with IDLEMODE_ENTER State */
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);
/* Wait for 1 SEC for LED to OFF */
@ -787,12 +727,10 @@ void SendIdleModeResponse(PMINI_ADAPTER Adapter)
down(&Adapter->rdmwrmsync);
Adapter->bPreparingForLowPowerMode = TRUE;
up(&Adapter->rdmwrmsync);
#ifndef BCM_SHM_INTERFACE
//Killing all URBS.
if(Adapter->bDoSuspend == TRUE)
Bcm_kill_all_URBs((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));
#endif
}
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");
Adapter->bPreparingForLowPowerMode = FALSE;
#ifndef BCM_SHM_INTERFACE
StartInterruptUrb((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));
#endif
}
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);
@ -980,12 +916,10 @@ VOID DumpPackInfo(PMINI_ADAPTER Adapter)
}
__inline int reset_card_proc(PMINI_ADAPTER ps_adapter)
int reset_card_proc(PMINI_ADAPTER ps_adapter)
{
int retval = STATUS_SUCCESS;
#ifndef BCM_SHM_INTERFACE
PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
PS_INTERFACE_ADAPTER psIntfAdapter = NULL;
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));
}
#ifndef BCM_SHM_INTERFACE
//killing all submitted URBs.
psIntfAdapter->psAdapter->StopAllXaction = TRUE ;
Bcm_kill_all_URBs(psIntfAdapter);
#endif
/* Reset the UMA-B Device */
if(ps_adapter->chip_id >= T3LPB)
{
@ -1111,11 +1043,10 @@ __inline int reset_card_proc(PMINI_ADAPTER ps_adapter)
err_exit :
psIntfAdapter->psAdapter->StopAllXaction = FALSE ;
#endif
return retval;
}
__inline int run_card_proc(PMINI_ADAPTER ps_adapter )
int run_card_proc(PMINI_ADAPTER ps_adapter )
{
unsigned int value=0;
{
@ -1146,21 +1077,17 @@ __inline int run_card_proc(PMINI_ADAPTER ps_adapter )
int InitCardAndDownloadFirmware(PMINI_ADAPTER ps_adapter)
{
UINT status = STATUS_SUCCESS;
int status;
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
* Firm/DDR Settings..
*/
if((status = create_worker_threads(ps_adapter))<0)
{
BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Cannot create thread");
status = create_worker_threads(ps_adapter);
if (status<0)
return status;
}
/*
* For Downloading the Firm, parse the cfg file first.
*/
@ -1169,7 +1096,6 @@ int InitCardAndDownloadFirmware(PMINI_ADAPTER ps_adapter)
return status;
}
#ifndef BCM_SHM_INTERFACE
if(ps_adapter->chip_id >= T3LPB)
{
rdmalt(ps_adapter, SYS_CFG, &value, sizeof (value));
@ -1187,7 +1113,7 @@ int InitCardAndDownloadFirmware(PMINI_ADAPTER ps_adapter)
status = ddr_init(ps_adapter);
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;
}
@ -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");
goto OUT;
}
BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "CFG file downloaded");
if(register_networkdev(ps_adapter))
{
@ -1266,12 +1191,6 @@ int InitCardAndDownloadFirmware(PMINI_ADAPTER ps_adapter)
goto OUT;
}
}
#if 0
else if(psAdapter->eNVMType == NVM_EEPROM)
{
PropagateCalParamsFromEEPROMToMemory();
}
#endif
/* Download Firmare */
if ((status = BcmFileDownload( ps_adapter, BIN_FILE, FIRMWARE_BEGIN_ADDR)))
@ -1280,7 +1199,6 @@ int InitCardAndDownloadFirmware(PMINI_ADAPTER ps_adapter)
goto OUT;
}
BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "BIN file downloaded");
status = run_card_proc(ps_adapter);
if(status)
{
@ -1299,68 +1217,19 @@ OUT:
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;
}
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;
mm_segment_t oldfs={0};
char *buff = NULL;
char *buff;
int len = 0;
loff_t pos = 0;
buff=(PCHAR)kmalloc(BUFFER_1K, GFP_KERNEL);
buff=kmalloc(BUFFER_1K, GFP_KERNEL);
if(!buff)
{
return -ENOMEM;
@ -1368,14 +1237,14 @@ int bcm_parse_target_params(PMINI_ADAPTER Adapter)
if((Adapter->pstargetparams =
kmalloc(sizeof(STARGETPARAMS), GFP_KERNEL)) == NULL)
{
bcm_kfree(buff);
kfree(buff);
return -ENOMEM;
}
flp=open_firmware_file(Adapter, CFG_FILE);
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_kfree(buff);
bcm_kfree(Adapter->pstargetparams);
kfree(buff);
kfree(Adapter->pstargetparams);
Adapter->pstargetparams = NULL;
return -ENOENT;
}
@ -1386,8 +1255,8 @@ int bcm_parse_target_params(PMINI_ADAPTER Adapter)
if(len != sizeof(STARGETPARAMS))
{
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Mismatch in Target Param Structure!\n");
bcm_kfree(buff);
bcm_kfree(Adapter->pstargetparams);
kfree(buff);
kfree(Adapter->pstargetparams);
Adapter->pstargetparams = NULL;
filp_close(flp, current->files);
return -ENOENT;
@ -1399,37 +1268,34 @@ int bcm_parse_target_params(PMINI_ADAPTER Adapter)
* Values in Adapter->pstargetparams are in network byte order
*/
memcpy(Adapter->pstargetparams, buff, sizeof(STARGETPARAMS));
bcm_kfree (buff);
kfree (buff);
beceem_parse_target_struct(Adapter);
#ifdef BCM_SHM_INTERFACE
read_cfg_file(Adapter);
#endif
return STATUS_SUCCESS;
}
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)
{
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;
}
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;
}
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;
}
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;
}
// Setting the DDR Setting..
@ -1438,59 +1304,54 @@ void beceem_parse_target_struct(PMINI_ADAPTER Adapter)
Adapter->ulPowerSaveMode =
(ntohl(Adapter->pstargetparams->HostDrvrConfig6)>>12)&0x0F;
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "DDR Setting: %x\n", Adapter->DDRSetting);
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT,DBG_LVL_ALL, "Power Save Mode: %lx\n",
Adapter->ulPowerSaveMode);
pr_info(DRV_NAME ": DDR Setting: %x\n", Adapter->DDRSetting);
pr_info(DRV_NAME ": Power Save Mode: %lx\n", Adapter->ulPowerSaveMode);
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;
}
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;
}
uiHostDrvrCfg6 = ntohl(Adapter->pstargetparams->HostDrvrConfig6);
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.
Adapter->bDPLLConfig = (uiHostDrvrCfg6>>19)&0x01;
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))
{
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);
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->bStatusWrite = (uiEEPROMFlag>>6)&0x1;
//printk(("bStatusWrite : 0x%X\n", Adapter->bStatusWrite));
Adapter->uiSectorSizeInCFG = 1024*(0xFFFF & ntohl(Adapter->pstargetparams->HostDrvrConfig4));
//printk(("uiSectorSize : 0x%X\n", Adapter->uiSectorSizeInCFG));
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)
Adapter->ulPowerSaveMode = DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE;
//autocorrection part
if(Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE)
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 ;
psAdapter->bIsAutoCorrectEnabled = !((char)(psAdapter->ulPowerSaveMode >> 3) & 0x1);
@ -1504,20 +1365,9 @@ VOID doPowerAutoCorrection(PMINI_ADAPTER psAdapter)
if (psAdapter->bIsAutoCorrectEnabled && (psAdapter->chip_id >= T3LPB))
{
//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->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
static unsigned char *ReadMacAddrEEPROM(PMINI_ADAPTER Adapter, ulong dwAddress)
{
unsigned char *pucmacaddr = NULL;
int status = 0, i=0;
unsigned int temp =0;
int status = 0, i = 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)
{
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)
{
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "wrm Failed..\n");
bcm_kfree(pucmacaddr);
kfree(pucmacaddr);
pucmacaddr = NULL;
goto OUT;
}
@ -1568,7 +1416,7 @@ static unsigned char *ReadMacAddrEEPROM(PMINI_ADAPTER Adapter, ulong dwAddress)
if(status != STATUS_SUCCESS)
{
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "rdm Failed..\n");
bcm_kfree(pucmacaddr);
kfree(pucmacaddr);
pucmacaddr = NULL;
goto OUT;
}
@ -1580,43 +1428,6 @@ OUT:
}
#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)
{
@ -1640,81 +1451,21 @@ int rdm(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize)
{
INT uiRetVal =0;
#ifndef BCM_SHM_INTERFACE
uiRetVal = Adapter->interface_rdm(Adapter->pvInterfaceAdapter,
uiAddress, pucBuff, sSize);
if(uiRetVal < 0)
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;
}
int wrm(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize)
{
int iRetVal;
#ifndef BCM_SHM_INTERFACE
iRetVal = Adapter->interface_wrm(Adapter->pvInterfaceAdapter,
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;
}
@ -1735,26 +1486,7 @@ int rdmalt (PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t size)
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 status = STATUS_SUCCESS ;
@ -1921,10 +1653,8 @@ static VOID SendShutModeResponse(PMINI_ADAPTER Adapter)
Adapter->bPreparingForLowPowerMode = TRUE;
up(&Adapter->rdmwrmsync);
//Killing all URBS.
#ifndef BCM_SHM_INTERFACE
if(Adapter->bDoSuspend == TRUE)
Bcm_kill_all_URBs((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter));
#endif
}
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");
Adapter->bPreparingForLowPowerMode = FALSE;
#ifndef BCM_SHM_INTERFACE
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;
@ -2077,11 +1805,7 @@ void update_per_sf_desc_cnts( PMINI_ADAPTER Adapter)
if(!atomic_read (&Adapter->uiMBupdate))
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)
#endif
{
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "rdm failed\n");
return;
@ -2107,9 +1831,7 @@ void update_per_sf_desc_cnts( PMINI_ADAPTER Adapter)
void flush_queue(PMINI_ADAPTER Adapter, UINT iQIndex)
{
struct sk_buff* PacketToDrop=NULL;
struct net_device_stats* netstats=NULL;
netstats = &((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats;
struct net_device_stats* netstats = &Adapter->dev->stats;
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].uiDroppedCountPackets++;
bcm_kfree_skb(PacketToDrop);
dev_kfree_skb(PacketToDrop);
atomic_dec(&Adapter->TotalPacketCount);
atomic_inc(&Adapter->TxDroppedPacketCount);
}
}
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)
{
netif_carrier_off(Adapter->dev);
netif_stop_queue(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);
Adapter->IdleMode = FALSE;
Adapter->LinkUpStatus = FALSE;
@ -2166,78 +1886,18 @@ void beceem_protocol_reset (PMINI_ADAPTER Adapter)
Adapter->TimerActive = FALSE;
memset(Adapter->astFragmentedPktClassifierTable, 0,
sizeof(S_FRAGMENTED_PACKET_INFO) *
MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES);
sizeof(S_FRAGMENTED_PACKET_INFO) * MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES);
for(i = 0;i<HiPriority;i++)
{
//resetting only the first size (S_MIBS_SERVICEFLOW_TABLE) for the 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

View File

@ -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));
}

View File

@ -1,10 +1,54 @@
#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 OUT
void DumpDataPacketHeader(PUCHAR pPkt);
/*
Function: PHSTransmit
@ -81,8 +125,6 @@ int PHSTransmit(PMINI_ADAPTER Adapter,
{
//DumpDataPacketHeader(pucPHSPktHdrInBuf);
// Step 2 Supress Header using PHS and fill into intermediate ucaPHSPktHdrOutBuf.
// Suppress only if IP Header and PHS Enabled For the Service Flow
if(((usPacketType == ETHERNET_FRAMETYPE_IPV4) ||
@ -120,15 +162,15 @@ int PHSTransmit(PMINI_ADAPTER Adapter,
if(newPacket == NULL)
return STATUS_FAILURE;
bcm_kfree_skb(Packet);
dev_kfree_skb(Packet);
*pPacket = Packet = newPacket;
pucPHSPktHdrInBuf = Packet->data + BytesToRemove;
}
numBytesCompressed = unPhsOldHdrSize - (unPHSNewPktHeaderLen+PHSI_LEN);
OsalMemMove(pucPHSPktHdrInBuf + numBytesCompressed, pucPHSPktHdrOutBuf, unPHSNewPktHeaderLen + PHSI_LEN);
OsalMemMove(Packet->data + numBytesCompressed, Packet->data, BytesToRemove);
memcpy(pucPHSPktHdrInBuf + numBytesCompressed, pucPHSPktHdrOutBuf, unPHSNewPktHeaderLen + PHSI_LEN);
memcpy(Packet->data + numBytesCompressed, Packet->data, BytesToRemove);
skb_pull(Packet, numBytesCompressed);
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;
}
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)
{
PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
@ -270,15 +301,9 @@ int phs_init(PPHS_DEVICE_EXTENSION pPhsdeviceExtension,PMINI_ADAPTER Adapter)
return -EINVAL;
pPhsdeviceExtension->pstServiceFlowPhsRulesTable =
(S_SERVICEFLOW_TABLE*)OsalMemAlloc(sizeof(S_SERVICEFLOW_TABLE),
PHS_MEM_TAG);
kzalloc(sizeof(S_SERVICEFLOW_TABLE), GFP_KERNEL);
if(pPhsdeviceExtension->pstServiceFlowPhsRulesTable)
{
OsalZeroMemory(pPhsdeviceExtension->pstServiceFlowPhsRulesTable,
sizeof(S_SERVICEFLOW_TABLE));
}
else
if(!pPhsdeviceExtension->pstServiceFlowPhsRulesTable)
{
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation ServiceFlowPhsRulesTable failed");
return -ENOMEM;
@ -288,14 +313,8 @@ int phs_init(PPHS_DEVICE_EXTENSION pPhsdeviceExtension,PMINI_ADAPTER Adapter)
for(i=0;i<MAX_SERVICEFLOWS;i++)
{
S_SERVICEFLOW_ENTRY sServiceFlow = pstServiceFlowTable->stSFList[i];
sServiceFlow.pstClassifierTable = (S_CLASSIFIER_TABLE*)OsalMemAlloc(
sizeof(S_CLASSIFIER_TABLE), PHS_MEM_TAG);
if(sServiceFlow.pstClassifierTable)
{
OsalZeroMemory(sServiceFlow.pstClassifierTable,sizeof(S_CLASSIFIER_TABLE));
pstServiceFlowTable->stSFList[i].pstClassifierTable = sServiceFlow.pstClassifierTable;
}
else
sServiceFlow.pstClassifierTable = kzalloc(sizeof(S_CLASSIFIER_TABLE), GFP_KERNEL);
if(!sServiceFlow.pstClassifierTable)
{
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed");
free_phs_serviceflow_rules(pPhsdeviceExtension->
@ -305,9 +324,7 @@ int phs_init(PPHS_DEVICE_EXTENSION pPhsdeviceExtension,PMINI_ADAPTER Adapter)
}
}
pPhsdeviceExtension->CompressedTxBuffer =
OsalMemAlloc(PHS_BUFFER_SIZE,PHS_MEM_TAG);
pPhsdeviceExtension->CompressedTxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL);
if(pPhsdeviceExtension->CompressedTxBuffer == NULL)
{
@ -317,12 +334,11 @@ int phs_init(PPHS_DEVICE_EXTENSION pPhsdeviceExtension,PMINI_ADAPTER Adapter)
return -ENOMEM;
}
pPhsdeviceExtension->UnCompressedRxBuffer =
OsalMemAlloc(PHS_BUFFER_SIZE,PHS_MEM_TAG);
pPhsdeviceExtension->UnCompressedRxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL);
if(pPhsdeviceExtension->UnCompressedRxBuffer == NULL)
{
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);
pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
return -ENOMEM;
@ -343,16 +359,11 @@ int PhsCleanup(IN PPHS_DEVICE_EXTENSION pPHSDeviceExt)
pPHSDeviceExt->pstServiceFlowPhsRulesTable = NULL;
}
if(pPHSDeviceExt->CompressedTxBuffer)
{
OsalMemFree(pPHSDeviceExt->CompressedTxBuffer,PHS_BUFFER_SIZE);
pPHSDeviceExt->CompressedTxBuffer = NULL;
}
if(pPHSDeviceExt->UnCompressedRxBuffer)
{
OsalMemFree(pPHSDeviceExt->UnCompressedRxBuffer,PHS_BUFFER_SIZE);
pPHSDeviceExt->UnCompressedRxBuffer = NULL;
}
kfree(pPHSDeviceExt->CompressedTxBuffer);
pPHSDeviceExt->CompressedTxBuffer = NULL;
kfree(pPHSDeviceExt->UnCompressedRxBuffer);
pPHSDeviceExt->UnCompressedRxBuffer = NULL;
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]
.pstPhsRule->u8PHSI == u8PHSI)
{
if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule
->u8RefCnt)
pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule
->u8RefCnt--;
if(0 == pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
.pstPhsRule->u8RefCnt)
OsalMemFree(pstClassifierRulesTable
->stActivePhsRulesList[nClsidIndex].pstPhsRule,
sizeof(S_PHS_RULE));
OsalZeroMemory(&pstClassifierRulesTable
->stActivePhsRulesList[nClsidIndex],
if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8PHSI == u8PHSI) {
if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt)
pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt--;
if(0 == pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt)
kfree(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule);
memset(&pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex], 0,
sizeof(S_CLASSIFIER_ENTRY));
}
}
@ -548,10 +551,10 @@ ULONG PhsDeleteClassifierRule(IN void* pvContext,IN B_UINT16 uiVcid ,IN B_UINT16
if(pstClassifierEntry->pstPhsRule->u8RefCnt)
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,
@ -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(pstClassifierEntry->pstPhsRule)
//Delete the classifier entry
OsalMemFree(pstClassifierEntry->pstPhsRule,sizeof(S_PHS_RULE));
OsalZeroMemory(pstClassifierEntry,sizeof(S_CLASSIFIER_ENTRY));
kfree(pstClassifierEntry->pstPhsRule);
memset(pstClassifierEntry, 0, sizeof(S_CLASSIFIER_ENTRY));
}
}
return lStatus;
@ -619,14 +620,11 @@ ULONG PhsDeleteSFRules(IN void* pvContext,IN B_UINT16 uiVcid)
.pstPhsRule->u8RefCnt--;
if(0==pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
.pstPhsRule->u8RefCnt)
OsalMemFree(pstClassifierRulesTable
->stActivePhsRulesList[nClsidIndex].pstPhsRule,
sizeof(S_PHS_RULE));
kfree(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule);
pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex]
.pstPhsRule = NULL;
}
OsalZeroMemory(&pstClassifierRulesTable
->stActivePhsRulesList[nClsidIndex],sizeof(S_CLASSIFIER_ENTRY));
memset(&pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex], 0, sizeof(S_CLASSIFIER_ENTRY));
if(pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule)
{
if(pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
@ -635,15 +633,12 @@ ULONG PhsDeleteSFRules(IN void* pvContext,IN B_UINT16 uiVcid)
.pstPhsRule->u8RefCnt--;
if(0 == pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
.pstPhsRule->u8RefCnt)
OsalMemFree(pstClassifierRulesTable
->stOldPhsRulesList[nClsidIndex].pstPhsRule,
sizeof(S_PHS_RULE));
kfree(pstClassifierRulesTable
->stOldPhsRulesList[nClsidIndex].pstPhsRule);
pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex]
.pstPhsRule = NULL;
}
OsalZeroMemory(&pstClassifierRulesTable
->stOldPhsRulesList[nClsidIndex],
sizeof(S_CLASSIFIER_ENTRY));
memset(&pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex], 0, sizeof(S_CLASSIFIER_ENTRY));
}
}
pstServiceFlowEntry->bUsed = FALSE;
@ -849,7 +844,7 @@ ULONG PhsDeCompress(IN void* pvContext,
// 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;
PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
@ -876,8 +871,7 @@ void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable)
->u8RefCnt--;
if(0==pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule
->u8RefCnt)
OsalMemFree(pstClassifierRulesTable->stActivePhsRulesList[j].
pstPhsRule, sizeof(S_PHS_RULE));
kfree(pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule);
pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule = NULL;
}
if(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule)
@ -888,24 +882,23 @@ void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable)
->u8RefCnt--;
if(0==pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule
->u8RefCnt)
OsalMemFree(pstClassifierRulesTable->stOldPhsRulesList[j]
.pstPhsRule,sizeof(S_PHS_RULE));
kfree(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule);
pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule = NULL;
}
}
OsalMemFree(pstClassifierRulesTable,sizeof(S_CLASSIFIER_TABLE));
kfree(pstClassifierRulesTable);
stServiceFlowEntry.pstClassifierTable = pstClassifierRulesTable = NULL;
}
}
}
OsalMemFree(psServiceFlowRulesTable,sizeof(S_SERVICEFLOW_TABLE));
psServiceFlowRulesTable = NULL;
kfree(psServiceFlowRulesTable);
psServiceFlowRulesTable = NULL;
}
BOOLEAN ValidatePHSRuleComplete(IN S_PHS_RULE *psPhsRule)
static BOOLEAN ValidatePHSRuleComplete(IN S_PHS_RULE *psPhsRule)
{
if(psPhsRule)
{
@ -988,9 +981,9 @@ UINT GetClassifierEntry(IN S_CLASSIFIER_TABLE *pstClassifierTable,
return PHS_INVALID_TABLE_INDEX;
}
UINT GetPhsRuleEntry(IN S_CLASSIFIER_TABLE *pstClassifierTable,
IN B_UINT32 uiPHSI,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,
OUT S_PHS_RULE **ppstPhsRule)
static UINT GetPhsRuleEntry(IN S_CLASSIFIER_TABLE *pstClassifierTable,
IN B_UINT32 uiPHSI,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,
OUT S_PHS_RULE **ppstPhsRule)
{
int i;
S_CLASSIFIER_ENTRY *pstClassifierRule = NULL;
@ -1102,7 +1095,7 @@ UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid,
if(psPhsRule->u8PHSFLength)
{
//update PHSF
OsalMemMove(pstClassifierEntry->pstPhsRule->u8PHSF,
memcpy(pstClassifierEntry->pstPhsRule->u8PHSF,
psPhsRule->u8PHSF , MAX_PHS_LENGTHS);
}
if(psPhsRule->u8PHSFLength)
@ -1114,7 +1107,7 @@ UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid,
if(psPhsRule->u8PHSMLength)
{
//update PHSM
OsalMemMove(pstClassifierEntry->pstPhsRule->u8PHSM,
memcpy(pstClassifierEntry->pstPhsRule->u8PHSM,
psPhsRule->u8PHSM, MAX_PHS_LENGTHS);
}
if(psPhsRule->u8PHSMLength)
@ -1147,7 +1140,7 @@ UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid,
return uiStatus;
}
UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId,
static UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId,
S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,
E_CLASSIFIER_ENTRY_CONTEXT eClsContext,B_UINT8 u8AssociatedPHSI)
{
@ -1234,8 +1227,7 @@ UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId,
{
if(psClassifierRules->pstPhsRule == NULL)
{
psClassifierRules->pstPhsRule = (S_PHS_RULE*)OsalMemAlloc
(sizeof(S_PHS_RULE),PHS_MEM_TAG);
psClassifierRules->pstPhsRule = kmalloc(sizeof(S_PHS_RULE),GFP_KERNEL);
if(NULL == psClassifierRules->pstPhsRule)
return ERR_PHSRULE_MEMALLOC_FAIL;
@ -1247,7 +1239,7 @@ UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId,
psClassifierRules->bUnclassifiedPHSRule = psPhsRule->bUnclassifiedPHSRule;
/* Update The PHS rule */
OsalMemMove(psClassifierRules->pstPhsRule,
memcpy(psClassifierRules->pstPhsRule,
psPhsRule, sizeof(S_PHS_RULE));
}
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,
S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,
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
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)
{
return ERR_PHSRULE_MEMALLOC_FAIL;
}
}
OsalMemMove(pstClassifierEntry->pstPhsRule, psPhsRule, sizeof(S_PHS_RULE));
memcpy(pstClassifierEntry->pstPhsRule, psPhsRule, sizeof(S_PHS_RULE));
}
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");
if(bPHSRuleOrphaned)
{
if(pstClassifierEntry->pstPhsRule)
{
//Just Free the PHS Rule as Ref Count is Zero
OsalMemFree(pstClassifierEntry->pstPhsRule,sizeof(S_PHS_RULE));
kfree(pstClassifierEntry->pstPhsRule);
pstClassifierEntry->pstPhsRule = NULL;
}
}
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)
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)
{
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
// 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
,unsigned char *out_buf,UINT *header_size,UINT *new_header_size)
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 *old_addr = out_buf;
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.
//-----------------------------------------------------------------------------
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 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)
{
unsigned int size=0;
int bit,i=0;

View File

@ -27,19 +27,6 @@ void DumpPhsRules(PPHS_DEVICE_EXTENSION pDeviceExtension);
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);
//Utility Functions
@ -52,42 +39,10 @@ ULONG PhsDeleteClassifierRule(void* pvContext, B_UINT16 uiVcid ,B_UINT16 uiClsI
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 ValidatePHSRuleComplete(S_PHS_RULE *psPhsRule);
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);

View File

@ -85,10 +85,10 @@ typedef struct _ETH_CS_ETH2_FRAME
ETH_HEADER_STRUC EThHdr;
} __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
typedef enum _E_SERVICEFLOW_CS_SPEC_
{

View File

@ -1,23 +1,12 @@
#ifndef _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 StatisticsResponse(PMINI_ADAPTER Adapter,PVOID pvBuffer);
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);
VOID DeleteAllClassifiersForSF(PMINI_ADAPTER Adapter,UINT uiSearchRuleIndex);
@ -38,25 +27,16 @@ VOID SortClassifiers(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);
INT SearchSfid(PMINI_ADAPTER Adapter,UINT uiSfid);
USHORT GetPacketQueueIndex(PMINI_ADAPTER Adapter, /**<Pointer to the driver control structure */
struct sk_buff* Packet /**< Pointer to the Packet to be sent*/
);
USHORT ClassifyPacket(PMINI_ADAPTER Adapter,struct sk_buff* skb);
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*/
struct sk_buff *Packet, /**<data buffer*/
@ -70,11 +50,9 @@ INT SendControlPacket(PMINI_ADAPTER Adapter, /**<Logical Adapter*/
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);
void unregister_networkdev(PMINI_ADAPTER Adapter);
INT AllocAdapterDsxBuffer(PMINI_ADAPTER Adapter);
@ -82,8 +60,6 @@ VOID AdapterFree(PMINI_ADAPTER Adapter);
INT FreeAdapterDsxBuffer(PMINI_ADAPTER Adapter);
int create_worker_threads(PMINI_ADAPTER psAdapter);
int tx_pkt_handler(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 bcm_parse_target_params(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);
void SendLinkDown(PMINI_ADAPTER Adapter);
void SendIdleModeResponse(PMINI_ADAPTER Adapter);
void HandleShutDownModeRequest(PMINI_ADAPTER Adapter,PUCHAR pucBuffer);
int ProcessGetHostMibs(PMINI_ADAPTER Adapter, PVOID ioBuffer,
ULONG inputBufferLength);
int GetDroppedAppCntrlPktMibs(PVOID ioBuffer, PPER_TARANG_DATA pTarang);
int ProcessGetHostMibs(PMINI_ADAPTER Adapter, S_MIBS_HOST_STATS_MIBS *buf);
void GetDroppedAppCntrlPktMibs(S_MIBS_HOST_STATS_MIBS *ioBuffer, PPER_TARANG_DATA pTarang);
void beceem_parse_target_struct(PMINI_ADAPTER Adapter);
void doPowerAutoCorrection(PMINI_ADAPTER psAdapter);
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,
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 beceem_protocol_reset (PMINI_ADAPTER Adapter);
void flush_queue(PMINI_ADAPTER Adapter, UINT iQIndex);
@ -164,31 +127,11 @@ INT BeceemEEPROMBulkRead(
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);
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 PropagateCalParamsFromEEPROMToMemory(PMINI_ADAPTER Adapter);
INT BeceemEEPROMBulkWrite(
PMINI_ADAPTER Adapter,
@ -198,11 +141,8 @@ INT BeceemEEPROMBulkWrite(
BOOLEAN bVerify);
INT ReadBeceemEEPROMBulk(PMINI_ADAPTER Adapter,UINT dwAddress, UINT *pdwData, UINT dwNumData);
INT ReadBeceemEEPROM(PMINI_ADAPTER Adapter,UINT dwAddress, UINT *pdwData);
NVM_TYPE BcmGetNvmType(PMINI_ADAPTER Adapter);
INT BeceemNVMRead(
PMINI_ADAPTER Adapter,
@ -217,24 +157,12 @@ INT BeceemNVMWrite(
UINT uiNumBytes,
BOOLEAN bVerify);
INT BcmUpdateSectorSize(PMINI_ADAPTER Adapter,UINT uiSectorSize);
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 BcmFlash2xBulkWrite(
@ -251,7 +179,6 @@ INT BcmFlash2xBulkRead(
FLASH2X_SECTION_VAL eFlashSectionVal,
UINT uiOffsetWithinSectionVal,
UINT uiNumBytes);
INT BcmGetSectionValEndOffset(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 validateFlash2xReadWrite(PMINI_ADAPTER Adapter, PFLASH2X_READWRITE psFlash2xReadWrite);
INT IsFlash2x(PMINI_ADAPTER Adapter);
INT GetFlashBaseAddr(PMINI_ADAPTER Adapter);
INT SaveHeaderIfPresent(PMINI_ADAPTER Adapter, PUCHAR pBuff, UINT uiSectAlignAddr);
INT BcmCopySection(PMINI_ADAPTER Adapter,
FLASH2X_SECTION_VAL SrcSection,
FLASH2X_SECTION_VAL DstSection,
UINT offset,
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);
@ -300,7 +206,6 @@ VOID OverrideServiceFlowParams(PMINI_ADAPTER Adapter,PUINT puiBuffer);
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 rdmWithLock(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,
unsigned long u32StartingAddress);
@ -309,11 +214,6 @@ INT buffDnldVerify(PMINI_ADAPTER Adapter, unsigned char *mappedbuffer, unsigned
VOID putUsbSuspend(struct work_struct *work);
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

View File

@ -4,15 +4,14 @@ This file contains the routines related to Quality of Service.
*/
#include "headers.h"
BOOLEAN MatchSrcIpAddress(S_CLASSIFIER_RULE *pstClassifierRule,ULONG ulSrcIP);
BOOLEAN MatchTos(S_CLASSIFIER_RULE *pstClassifierRule,UCHAR ucTypeOfService);
BOOLEAN MatchSrcPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushSrcPort);
BOOLEAN MatchDestPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushDestPort);
BOOLEAN MatchProtocol(S_CLASSIFIER_RULE *pstClassifierRule,UCHAR ucProtocol);
BOOLEAN MatchDestIpAddress(S_CLASSIFIER_RULE *pstClassifierRule,ULONG ulDestIP);
USHORT ClassifyPacket(PMINI_ADAPTER Adapter,struct sk_buff* skb);
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);
static void EThCSGetPktInfo(PMINI_ADAPTER Adapter,PVOID pvEthPayload,PS_ETHCS_PKT_INFO pstEthCsPktInfo);
static BOOLEAN EThCSClassifyPkt(PMINI_ADAPTER Adapter,struct sk_buff* skb,PS_ETHCS_PKT_INFO pstEthCsPktInfo,S_CLASSIFIER_RULE *pstClassifierRule, B_UINT8 EthCSCupport);
static USHORT IpVersion4(PMINI_ADAPTER Adapter, struct iphdr *iphd,
S_CLASSIFIER_RULE *pstClassifierRule );
static VOID PruneQueue(PMINI_ADAPTER Adapter, INT iIndex);
/*******************************************************************
* Function - MatchSrcIpAddress()
@ -205,11 +204,10 @@ BOOLEAN MatchDestPort(S_CLASSIFIER_RULE *pstClassifierRule,USHORT ushDestPort)
Compares IPV4 Ip address and port number
@return Queue Index.
*/
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 )
static USHORT IpVersion4(PMINI_ADAPTER Adapter,
struct iphdr *iphd,
S_CLASSIFIER_RULE *pstClassifierRule )
{
//IPHeaderFormat *pIpHeader=NULL;
xporthdr *xprt_hdr=NULL;
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(iphd->protocol!=TCP && iphd->protocol!=UDP)
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 *****************//
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);
@ -312,29 +301,6 @@ USHORT IpVersion4(PMINI_ADAPTER Adapter, /**< Pointer to the driver control stru
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)
{
@ -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
less than or equal to max queue size for the queue.
*/
VOID PruneQueue(PMINI_ADAPTER Adapter,/**<Pointer to the driver control structure*/
INT iIndex/**<Queue Index*/
)
static VOID PruneQueue(PMINI_ADAPTER Adapter, INT iIndex)
{
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);
if(iIndex == HiPriority)
return;
return;
if(!Adapter || (iIndex < 0) || (iIndex > HiPriority))
return;
/* To Store the netdevice statistic */
netstats = &((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats;
netstats = &Adapter->dev->stats;
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(netstats)
netstats->tx_dropped++;
atomic_inc(&Adapter->TxDroppedPacketCount);
struct netdev_queue *txq = netdev_get_tx_queue(Adapter->dev, iIndex);
if (netif_msg_tx_err(Adapter))
pr_info(PFX "%s: tx queue %d overlimit\n",
Adapter->dev->name, iIndex);
txq->tx_dropped++;
DEQUEUEPACKET(Adapter->PackInfo[iIndex].FirstTxQueue,
Adapter->PackInfo[iIndex].LastTxQueue);
/// 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
Adapter->PackInfo[iIndex].uiDroppedCountBytes += PacketToDrop->len;
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);
atomic_dec(&Adapter->TotalPacketCount);
Adapter->bcm_jiffies = jiffies;
}
spin_unlock_bh(&Adapter->PackInfo[iIndex].SFQueueLock);
@ -430,16 +397,15 @@ VOID flush_all_queues(PMINI_ADAPTER Adapter)
{
INT iQIndex;
UINT uiTotalPacketLength;
struct sk_buff* PacketToDrop=NULL;
struct net_device_stats* netstats=NULL;
struct sk_buff* PacketToDrop=NULL;
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);
for(iQIndex=LowPriority; iQIndex<HiPriority; iQIndex++)
{
struct netdev_queue *txq = netdev_get_tx_queue(Adapter->dev, iQIndex);
spin_lock_bh(&Adapter->PackInfo[iQIndex].SFQueueLock);
while(Adapter->PackInfo[iQIndex].FirstTxQueue)
{
@ -447,8 +413,7 @@ VOID flush_all_queues(PMINI_ADAPTER Adapter)
if(PacketToDrop)
{
uiTotalPacketLength = PacketToDrop->len;
netstats->tx_dropped++;
atomic_inc(&Adapter->TxDroppedPacketCount);
txq->tx_dropped++;
}
else
uiTotalPacketLength = 0;
@ -457,7 +422,7 @@ VOID flush_all_queues(PMINI_ADAPTER Adapter)
Adapter->PackInfo[iQIndex].LastTxQueue);
/* Free the skb */
bcm_kfree_skb(PacketToDrop);
dev_kfree_skb(PacketToDrop);
/// update current bytes and packets count
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--)
{
if (Adapter->device_removed)
{
bClassificationSucceed = FALSE;
break;
}
if(bClassificationSucceed)
break;
//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;
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;
}
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);
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "EthCSGetPktInfo : Eth Hdr Type : %X\n",u16Etype);
if(u16Etype > 0x5dc)
{

View File

@ -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:
- 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
- sparse warnings
- checkpatch warnings
- remove compatiablity code for older kernels
- remove #ifdef's
- fix bogus device nameing and reference counting (see bcm_notify_event)
- fix use of file I/O to load config
- request firmware
- update to current network device API
- merge some files together
- use request firmware
- fix use of file I/O to load config with better API
- merge some files together?
- cleanup/eliminate debug messages
- integrate with existing Wimax stack?

View File

@ -6,7 +6,7 @@
digraph transmit1 {
node[shape=box]
edge[weight=5;color=red]
bcm_transmit->reply_to_arp_request[label="ARP"]
bcm_transmit->GetPacketQueueIndex[label="IP Packet"]
GetPacketQueueIndex->IpVersion4[label="IPV4"]
GetPacketQueueIndex->IpVersion6[label="IPV6"]
@ -35,169 +35,16 @@ SendPacketFromQueue->SetupNextSend->bcm_cmd53
#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
This function dispatches control packet to the h/w interface
@return zero(success) or -ve value(failure)
*/
INT SendControlPacket(PMINI_ADAPTER Adapter, /**<Logical Adapter*/
char *pControlPacket/**<Control Packet*/
)
INT SendControlPacket(PMINI_ADAPTER Adapter, char *pControlPacket)
{
PLEADER PLeader = NULL;
struct timeval tv;
memset(&tv, 0, sizeof(tv));
PLEADER PLeader = (PLEADER)pControlPacket;
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");
if(!pControlPacket || !Adapter)
{
@ -208,12 +55,6 @@ INT SendControlPacket(PMINI_ADAPTER Adapter, /**<Logical Adapter*/
((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");
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;
}
@ -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);
if(Adapter->device_removed)
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,
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);
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "<=========");
return STATUS_SUCCESS;
}
static LEADER Leader={0};
/**
@ingroup tx_functions
This function despatches the IP packets with the given vcid
to the target via the host h/w interface.
@return zero(success) or -ve value(failure)
*/
INT SetupNextSend(PMINI_ADAPTER Adapter, /**<Logical Adapter*/
struct sk_buff *Packet, /**<data buffer*/
USHORT Vcid) /**<VCID for this packet*/
INT SetupNextSend(PMINI_ADAPTER Adapter, struct sk_buff *Packet, USHORT Vcid)
{
int status=0;
#ifdef GDMA_INTERFACE
int dontfree = 0;
#endif
BOOLEAN bHeaderSupressionEnabled = FALSE;
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)
{
status = STATUS_FAILURE;
@ -302,14 +100,10 @@ INT SetupNextSend(PMINI_ADAPTER Adapter, /**<Logical Adapter*/
/* Get the Classifier Rule ID */
uiClassifierRuleID = *((UINT32*) (Packet->cb)+SKB_CB_CLASSIFICATION_OFFSET);
QueueIndex = SearchVcid( Adapter,Vcid);
if(QueueIndex < NO_OF_QUEUES)
{
bHeaderSupressionEnabled =
Adapter->PackInfo[QueueIndex].bHeaderSuppressionEnabled;
bHeaderSupressionEnabled =
bHeaderSupressionEnabled & Adapter->bPHSEnabled;
}
bHeaderSupressionEnabled = Adapter->PackInfo[QueueIndex].bHeaderSuppressionEnabled
& Adapter->bPHSEnabled;
if(Adapter->device_removed)
{
status = STATUS_FAILURE;
@ -327,15 +121,10 @@ INT SetupNextSend(PMINI_ADAPTER Adapter, /**<Logical Adapter*/
Leader.Vcid = Vcid;
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");
if(TCP_ACK == *((UINT32*) (Packet->cb) + SKB_CB_TCPACK_OFFSET ))
Leader.Status = LEADER_STATUS_TCP_ACK;
}
else
{
Leader.Status = LEADER_STATUS;
}
if(Adapter->PackInfo[QueueIndex].bEthCSSupport)
{
@ -351,68 +140,53 @@ INT SetupNextSend(PMINI_ADAPTER Adapter, /**<Logical Adapter*/
skb_push(Packet, LEADER_SIZE);
memcpy(Packet->data, &Leader, LEADER_SIZE);
}
else
{
Leader.PLength = Packet->len - ETH_HLEN;
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,
Packet->data, (Leader.PLength + LEADER_SIZE));
#else
status = tx_pkts_to_firmware(Packet,Packet->len,0);
#endif
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
{
struct netdev_queue *txq = netdev_get_tx_queue(Adapter->dev, QueueIndex);
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].uiSentBytes += (Packet->len);
Adapter->PackInfo[QueueIndex].uiSentPackets++;
Adapter->PackInfo[QueueIndex].NumOfPacketsSent++;
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;
}
atomic_dec(&Adapter->CurrNumFreeTxDesc);
#ifdef GDMA_INTERFACE
if(!dontfree){
bcm_kfree_skb(Packet);
}
#else
bcm_kfree_skb(Packet);
#endif
errExit:
dev_kfree_skb(Packet);
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
Transmit thread
@ -420,57 +194,26 @@ Transmit thread
int tx_pkt_handler(PMINI_ADAPTER Adapter /**< pointer to adapter object*/
)
{
#ifndef BCM_SHM_INTERFACE
int status = 0;
#endif
UINT calltransmit = 1;
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);
while(1)
{
if(Adapter->LinkUpStatus){
while(! kthread_should_stop()) {
/* FIXME - the timeout looks like workaround for racey usage of TxPktAvail */
if(Adapter->LinkUpStatus)
wait_event_timeout(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
, 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
);
}
tx_pending(Adapter), msecs_to_jiffies(10));
else
wait_event_interruptible(Adapter->tx_packet_wait_queue,
tx_pending(Adapter));
if(kthread_should_stop() || Adapter->device_removed)
{
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->device_removed)
break;
if(Adapter->downloadDDR == 1)
{
BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Downloading DDR Settings\n");
Adapter->downloadDDR +=1;
status = download_ddr_settings(Adapter);
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;
}
@ -489,7 +232,6 @@ int tx_pkt_handler(PMINI_ADAPTER Adapter /**< pointer to adapter object*/
update_per_sf_desc_cnts(Adapter);
}
}
#endif
if( atomic_read(&Adapter->CurrNumFreeTxDesc) &&
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);
}
#ifdef BCM_SHM_INTERFACE
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);
transmit_packets(Adapter);
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;
}
#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

View File

@ -2,19 +2,6 @@
#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
@ -28,7 +15,6 @@ extern B_UINT32 g_u32Corr2MacFlags;
#define DSD_ACK 19
#define MAX_CLASSIFIERS_IN_SF 4
#endif
#define MAX_STRING_LEN 20
#define MAX_PHS_LENGTHS 255
@ -57,37 +43,7 @@ extern B_UINT32 g_u32Corr2MacFlags;
////////////////////////structure Definitions///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// \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{
#endif
/** 16bit UserPriority Of The Service Flow*/
B_UINT16 u16UserPriority;
@ -145,29 +101,10 @@ struct _stCPacketClassificationRuleSI{
B_UINT8 u8ClassifierActionRule;
B_UINT16 u16ValidityBitMap;
};
#ifndef BECEEM_TARGET
typedef struct _stCPacketClassificationRuleSI CCPacketClassificationRuleSI,stCPacketClassificationRuleSI, *pstCPacketClassificationRuleSI;
#endif
/// \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 {
#endif
/** 8bit PHS Index Of The Service Flow*/
B_UINT8 u8PHSI;
/** PHSF Length Of The Service Flow*/
@ -188,31 +125,11 @@ typedef struct _stPhsRuleSI {
B_UINT8 u8VendorSpecificPHSParams[VENDOR_PHS_PARAM_LENGTH];
B_UINT8 u8Padding[2];
#ifdef BECEEM_TARGET
};
#else
}stPhsRuleSI,*pstPhsRuleSI;
typedef stPhsRuleSI CPhsRuleSI;
#endif
/// \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{
#endif
/** 8bit Phs Classfier Action Of The Service Flow*/
B_UINT8 u8ClassfierDSCAction;
/** 8bit Phs DSC Action Of The Service Flow*/
@ -220,111 +137,15 @@ struct _stConvergenceSLTypes{
/** 16bit Padding */
B_UINT8 u8Padding[2];
/// \brief class cCPacketClassificationRule
#ifdef BECEEM_TARGET
CCPacketClassificationRuleSI cCPacketClassificationRule;
#else
stCPacketClassificationRuleSI cCPacketClassificationRule;
#endif
/// \brief class CPhsRuleSI
#ifdef BECEEM_TARGET
CPhsRuleSI cPhsRule;
#else
struct _stPhsRuleSI cPhsRule;
#endif
};
#ifndef BECEEM_TARGET
typedef struct _stConvergenceSLTypes stConvergenceSLTypes,CConvergenceSLTypes, *pstConvergenceSLTypes;
#endif
/// \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{
#endif //end of ifdef BECEEM_TARGET
/** 32bitSFID Of The Service Flow*/
B_UINT32 u32SFID;
@ -367,11 +188,6 @@ typedef struct _stServiceFlowParamSI{
/** 16bit ARQ Purge timeout */
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
/// \brief Size of an ARQ block
B_UINT16 u16ARQBlockSize;
@ -496,35 +312,18 @@ typedef struct _stServiceFlowParamSI{
B_UINT8 bValid; /**< Validity flag */
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
*/
stConvergenceSLTypes cConvergenceSLTypes[MAX_CLASSIFIERS_IN_SF];
#endif
#ifdef BECEEM_TARGET
};
#else
} stServiceFlowParamSI, *pstServiceFlowParamSI;
typedef stServiceFlowParamSI CServiceFlowParamSI;
#endif
/**
structure 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 eConnectionDir; /**< Connection direction*/
@ -535,19 +334,9 @@ typedef struct _stLocalSFAddRequest{
/// \brief 16bitVCID
B_UINT16 u16VCID; /**< 16bit VCID*/
/// \brief structure ParameterSet
#ifdef BECEEM_SIGNALLING_INTERFACE_API
CServiceFlowParamSI sfParameterSet;
#endif
#ifdef BECEEM_TARGET
CServiceFlowParamSI *psfParameterSet;
#else
stServiceFlowParamSI *psfParameterSet; /**< structure ParameterSet*/
#endif
#ifdef USING_VXWORKS
USE_DATA_MEMORY_MANAGER();
#endif
}stLocalSFAddRequest, *pstLocalSFAddRequest;
@ -555,12 +344,6 @@ typedef struct _stLocalSFAddRequest{
structure 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 eConnectionDir; /**< Connection Direction*/
@ -571,37 +354,19 @@ typedef struct _stLocalSFAddIndication{
/// \brief 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
#ifdef BECEEM_TARGET
CServiceFlowParamSI *psfAuthorizedSet;
/// \brief structure AdmittedSet
CServiceFlowParamSI *psfAdmittedSet;
/// \brief structure ActiveSet
CServiceFlowParamSI *psfActiveSet;
#else
/// \brief structure AuthorizedSet
stServiceFlowParamSI *psfAuthorizedSet; /**< AuthorizedSet of type stServiceFlowParamSI*/
/// \brief structure AdmittedSet
stServiceFlowParamSI *psfAdmittedSet; /**< AdmittedSet of type stServiceFlowParamSI*/
/// \brief structure ActiveSet
stServiceFlowParamSI *psfActiveSet; /**< sfActiveSet of type stServiceFlowParamSI*/
#endif
B_UINT8 u8CC; /**< Confirmation Code*/
B_UINT8 u8Padd; /**< 8-bit Padding */
B_UINT16 u16Padd; /**< 16 bit Padding */
#ifdef USING_VXWORKS
USE_DATA_MEMORY_MANAGER();
#endif
}stLocalSFAddIndication;
@ -619,33 +384,17 @@ typedef struct _stLocalSFAddIndication stLocalSFChangeIndication, *pstLocalSFCha
structure stLocalSFDeleteRequest
*/
typedef struct _stLocalSFDeleteRequest{
#ifdef BECEEM_TARGET
_stLocalSFDeleteRequest( ) :
u8Type(0x00), u8Padding(0x00),
u16TID(0x0000), u32SFID (0x00000000)
{}
#endif
B_UINT8 u8Type; /**< Type*/
B_UINT8 u8Padding; /**< Padding byte*/
B_UINT16 u16TID; /**< TID*/
/// \brief 32bitSFID
B_UINT32 u32SFID; /**< SFID*/
#ifdef USING_VXWORKS
USE_DATA_MEMORY_MANAGER();
#endif
}stLocalSFDeleteRequest, *pstLocalSFDeleteRequest;
/**
structure 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 u8Padding; /**< Padding */
B_UINT16 u16TID; /**< TID */
@ -658,9 +407,6 @@ typedef struct stLocalSFDeleteIndication{
/// \brief 8bit Confirmation code
B_UINT8 u8ConfirmationCode; /**< Confirmation code */
B_UINT8 u8Padding1[3]; /**< 3 byte Padding */
#ifdef USING_VXWORKS
USE_DATA_MEMORY_MANAGER();
#endif
}stLocalSFDeleteIndication;
typedef struct _stIM_SFHostNotify

View File

@ -22,7 +22,6 @@
#include <linux/etherdevice.h>
#include <net/ip.h>
#include <linux/wait.h>
#include <linux/notifier.h>
#include <linux/proc_fs.h>
#include <linux/interrupt.h>
@ -36,26 +35,10 @@
#include <linux/mm.h>
#include <linux/pagemap.h>
#include <asm/uaccess.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
#include <linux/kthread.h>
#endif
#include <linux/tcp.h>
#include <linux/udp.h>
#ifndef BCM_SHM_INTERFACE
#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 "Version.h"
@ -71,39 +54,28 @@ extern B_UINT32 g_u32Corr2MacFlags;
#include "CmHost.h"
#include "DDRInit.h"
#include "Debug.h"
#include "HostMibs.h"
#include "IPv6ProtocolHdr.h"
#include "osal_misc.h"
#include "PHSModule.h"
#include "Protocol.h"
#include "Prototypes.h"
#include "Queue.h"
#include "vendorspecificextn.h"
#ifndef BCM_SHM_INTERFACE
#include "InterfaceMacros.h"
#include "InterfaceAdapter.h"
#include "InterfaceIsr.h"
#include "Interfacemain.h"
#include "InterfaceMisc.h"
#include "InterfaceRx.h"
#include "InterfaceTx.h"
#endif
#include "InterfaceIdleMode.h"
#include "InterfaceInit.h"
#ifdef BCM_SHM_INTERFACE
#include <linux/cpe_config.h>
#ifdef GDMA_INTERFACE
#include "GdmaInterface.h"
#include "symphony.h"
#else
#include "virtual_interface.h"
#endif
#endif
#define DRV_NAME "beceem"
#define DEV_NAME "tarang"
#define DRV_DESCRIPTION "Beceem Communications Inc. WiMAX driver"
#define DRV_COPYRIGHT "Copyright 2010. Beceem Communications Inc"
#define DRV_VERSION VER_FILEVERSION_STR
#define PFX DRV_NAME " "
#endif

View File

@ -10,12 +10,8 @@
*/
#include "headers.h"
INT ProcessGetHostMibs(PMINI_ADAPTER Adapter,
PVOID ioBuffer,
ULONG inputBufferLength)
INT ProcessGetHostMibs(PMINI_ADAPTER Adapter, S_MIBS_HOST_STATS_MIBS *pstHostMibs)
{
S_MIBS_HOST_STATS_MIBS *pstHostMibs = NULL;
S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL;
S_PHS_RULE *pstPhsRule = NULL;
S_CLASSIFIER_TABLE *pstClassifierTable = NULL;
@ -30,15 +26,6 @@ INT ProcessGetHostMibs(PMINI_ADAPTER Adapter,
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
for(nClassifierIndex=0; nClassifierIndex < MAX_CLASSIFIERS;
nClassifierIndex++)
@ -54,7 +41,7 @@ INT ProcessGetHostMibs(PMINI_ADAPTER Adapter,
{
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
{
@ -83,7 +70,7 @@ INT ProcessGetHostMibs(PMINI_ADAPTER Adapter,
pstHostMibs->astPhsRulesTable[nPhsTableIndex].ulSFID = Adapter->PackInfo[nSfIndex].ulSFID;
OsalMemMove(&pstHostMibs->astPhsRulesTable[nPhsTableIndex].u8PHSI,
memcpy(&pstHostMibs->astPhsRulesTable[nPhsTableIndex].u8PHSI,
&pstPhsRule->u8PHSI,
sizeof(S_PHS_RULE));
nPhsTableIndex++;
@ -95,12 +82,9 @@ INT ProcessGetHostMibs(PMINI_ADAPTER Adapter,
}
//copy other Host Statistics parameters
pstHostMibs->stHostInfo.GoodTransmits =
atomic_read(&Adapter->TxTotalPacketCount);
pstHostMibs->stHostInfo.GoodReceives =
atomic_read(&Adapter->GoodRxPktCount);
pstHostMibs->stHostInfo.GoodTransmits = Adapter->dev->stats.tx_packets;
pstHostMibs->stHostInfo.GoodReceives = Adapter->dev->stats.rx_packets;
pstHostMibs->stHostInfo.CurrNumFreeDesc =
atomic_read(&Adapter->CurrNumFreeTxDesc);
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((PVOID)&(pstHostMibs->stDroppedAppCntrlMsgs),(PVOID)&(pTarang->stDroppedAppCntrlMsgs),sizeof(S_MIBS_DROPPED_APP_CNTRL_MESSAGES));
return STATUS_SUCCESS ;
memcpy(&(pstHostMibs->stDroppedAppCntrlMsgs),
&(pTarang->stDroppedAppCntrlMsgs),sizeof(S_MIBS_DROPPED_APP_CNTRL_MESSAGES));
}

View File

@ -108,52 +108,16 @@ static INT LED_Proportional_Blink(PMINI_ADAPTER Adapter, UCHAR GPIO_Num_tx,
ulong timeout = 0;
/*Read initial value of packets sent/received */
Initial_num_of_packts_tx = atomic_read(&Adapter->TxTotalPacketCount);
Initial_num_of_packts_rx = atomic_read(&Adapter->GoodRxPktCount);
Initial_num_of_packts_tx = Adapter->dev->stats.tx_packets;
Initial_num_of_packts_rx = Adapter->dev->stats.rx_packets;
/*Scale the rate of transfer to no of blinks.*/
num_of_time_tx= ScaleRateofTransfer((ULONG)rate_of_transfer_tx);
num_of_time_rx= ScaleRateofTransfer((ULONG)rate_of_transfer_rx);
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;
#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*/
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
* 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;
Final_num_of_packts_rx = atomic_read(&Adapter->GoodRxPktCount);
rate_of_transfer_rx = Final_num_of_packts_rx - Initial_num_of_packts_rx;
/*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);
puBuffer = OsalMemAlloc(usParamLen,"!MEM");
puBuffer = kmalloc(usParamLen, GFP_KERNEL);
if(!puBuffer)
{
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:
if(puBuffer)
{
OsalMemFree(puBuffer, usParamLen);
}
kfree(puBuffer);
return Status;
}
@ -497,12 +459,10 @@ static int ReadConfigFileStructure(PMINI_ADAPTER Adapter, BOOLEAN *bEnableThread
{
int Status = STATUS_SUCCESS;
UCHAR GPIO_Array[NUM_OF_LEDS+1]; /*Array to store GPIO numbers from EEPROM*/
#ifndef BCM_SHM_INTERFACE
UINT uiIndex = 0;
UINT uiNum_of_LED_Type = 0;
PUCHAR puCFGData = NULL;
UCHAR bData = 0;
#endif
memset(GPIO_Array, DISABLE_GPIO_NUM, NUM_OF_LEDS+1);
if(!Adapter->pstargetparams || IS_ERR(Adapter->pstargetparams))
@ -524,10 +484,6 @@ static int ReadConfigFileStructure(PMINI_ADAPTER Adapter, BOOLEAN *bEnableThread
*bEnableThread = FALSE;
return Status;
}
#ifdef BCM_SHM_INTERFACE
*bEnableThread = FALSE;
return Status ;
#else
/*
* CONFIG file read successfully. Deallocate the memory of
* uiFileNameBufferSize
@ -578,23 +534,7 @@ static int ReadConfigFileStructure(PMINI_ADAPTER Adapter, BOOLEAN *bEnableThread
}
if(uiNum_of_LED_Type >= NUM_OF_LEDS)
*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;
}
//--------------------------------------------------------------------------
@ -721,20 +661,6 @@ static VOID LEDControlThread(PMINI_ADAPTER Adapter)
TURN_OFF_LED(1<<GPIO_num, uiLedIndex);
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)
{
@ -752,10 +678,6 @@ static VOID LEDControlThread(PMINI_ADAPTER Adapter)
case DRIVER_INIT:
{
currdriverstate = DRIVER_INIT;//Adapter->DriverState;
#if 0
LedGpioInit(Adapter);
Adapter->LEDInfo.bLedInitDone = TRUE;
#endif
BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum, &uiLedIndex, &dummyIndex, currdriverstate);
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");
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);
if(GPIO_num != DISABLE_GPIO_NUM)
@ -796,12 +711,6 @@ static VOID LEDControlThread(PMINI_ADAPTER Adapter)
break;
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.
case NO_NETWORK_ENTRY:
@ -875,34 +784,6 @@ static VOID LEDControlThread(PMINI_ADAPTER Adapter)
break;
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;
case DRIVER_HALT:

File diff suppressed because it is too large Load Diff

View File

@ -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_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))
#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

View File

@ -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

View File

@ -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
https://git.kernel.org/?p=linux/kernel/git/dwmw2/linux-firmware.git
For all chips, copy brcm/bcm43xx-0-610-809-0.fw and
brcm/bcm43xx_hdr-0-610-809-0.fw to /lib/firmware/brcm (or wherever firmware is
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
For all chips, copy brcm/bcm43xx-0.fw and brcm/bcm43xx_hdr-0.fw to
/lib/firmware/brcm (or wherever firmware is normally installed on your system).
Currently supported chips
==============

View File

@ -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
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
bcm4329-fullmac-4-218-248-5.txt to /lib/firmware/brcm
For 4329 chip, copy brcm/bcm4329-fullmac-4.bin and brcm/bcm4329-fullmac-4.txt
to /lib/firmware/brcm (or wherever firmware is normally installed on your
system).
Contact Info:
=============

View File

@ -16,13 +16,14 @@
/* ****************** BCMSDH Interface Functions *************************** */
#include <linux/types.h>
#include <linux/netdevice.h>
#include <bcmdefs.h>
#include <bcmdevs.h>
#include <bcmendian.h>
#include <osl.h>
#include <bcmutils.h>
#include <hndsoc.h>
#include <siutils.h>
#include <osl.h>
#include <bcmsdh.h> /* BRCM API for SDIO
clients (such as wl, dhd) */
@ -38,7 +39,7 @@ struct bcmsdh_info {
bool init_success; /* underlying driver successfully attached */
void *sdioh; /* handler for sdioh */
u32 vendevid; /* Target Vendor and Device ID on SD bus */
osl_t *osh;
struct osl_info *osh;
bool regfail; /* Save status of last
reg_read/reg_write call */
u32 sbwad; /* Save backplane window address */
@ -55,7 +56,8 @@ void bcmsdh_enable_hw_oob_intr(bcmsdh_info_t *sdh, bool enable)
}
#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;
@ -84,7 +86,7 @@ bcmsdh_info_t *bcmsdh_attach(osl_t *osh, void *cfghdl, void **regsva, uint irq)
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;
@ -451,7 +453,7 @@ bool bcmsdh_regfail(void *sdh)
int
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_info_t *bcmsdh = (bcmsdh_info_t *) sdh;

View File

@ -20,8 +20,7 @@
#define __UNDEF_NO_VERSION__
#include <linuxver.h>
#include <linux/netdevice.h>
#include <linux/pci.h>
#include <linux/completion.h>
@ -57,7 +56,7 @@ struct bcmsdh_hc {
#else
struct pci_dev *dev; /* pci device handle */
#endif /* BCMPLATFORM_BUS */
osl_t *osh;
struct osl_info *osh;
void *regs; /* SDIO Host Controller address */
bcmsdh_info_t *sdh; /* SDIO Host Controller handle */
void *ch;
@ -138,23 +137,12 @@ static int __devinit bcmsdh_probe(struct device *dev);
static int __devexit bcmsdh_remove(struct device *dev);
#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
static
#endif /* BCMLXSDMMC */
int bcmsdh_probe(struct device *dev)
{
osl_t *osh = NULL;
struct osl_info *osh = NULL;
bcmsdh_hc_t *sdhc = NULL;
unsigned long regs = 0;
bcmsdh_info_t *sdh = NULL;
@ -189,7 +177,7 @@ int bcmsdh_probe(struct device *dev)
}
#endif /* defined(OOB_INTR_ONLY) */
/* allocate SDIO Host Controller state info */
osh = osl_attach(dev, PCI_BUS, false);
osh = osl_attach(dev, PCI_BUS);
if (!osh) {
SDLX_MSG(("%s: osl_attach failed\n", __func__));
goto err;
@ -258,7 +246,7 @@ static
int bcmsdh_remove(struct device *dev)
{
bcmsdh_hc_t *sdhc, *prev;
osl_t *osh;
struct osl_info *osh;
sdhc = sdhcinfo;
drvinfo.detach(sdhc->ch);
@ -291,269 +279,23 @@ int bcmsdh_remove(struct device *dev)
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 **)&regs, 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 */
extern int sdio_function_init(void);
int bcmsdh_register(bcmsdh_driver_t *driver)
{
int error = 0;
drvinfo = *driver;
#if defined(BCMPLATFORM_BUS)
#if defined(BCMLXSDMMC)
SDLX_MSG(("Linux Kernel SDIO/MMC Driver\n"));
error = 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;
return sdio_function_init();
}
extern void sdio_function_cleanup(void);
void bcmsdh_unregister(void)
{
#if defined(BCMPLATFORM_BUS) && !defined(BCMLXSDMMC)
driver_unregister(&bcmsdh_driver);
#endif
#if defined(BCMLXSDMMC)
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)

View File

@ -14,11 +14,12 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <linux/types.h>
#include <linux/netdevice.h>
#include <bcmdefs.h>
#include <bcmdevs.h>
#include <bcmendian.h>
#include <bcmutils.h>
#include <osl.h>
#include <bcmutils.h>
#include <sdio.h> /* SDIO Device and Protocol Specs */
#include <sdioh.h> /* SDIO Host Controller Specification */
#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
*/
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;
int err_ret;
@ -174,7 +175,7 @@ extern sdioh_info_t *sdioh_attach(osl_t *osh, void *bar0, uint irq)
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__));
@ -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));
if (!sd->func_cis_ptr[func]) {
bzero(cis, length);
memset(cis, 0, length);
sd_err(("%s: no func_cis_ptr[%d]\n", __func__, func));
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
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);
u32 SGCount = 0;
int err_ret = 0;
void *pnext;
struct sk_buff *pnext;
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 */
sdio_claim_host(gInstance->func[func]);
for (pnext = pkt; pnext; pnext = PKTNEXT(pnext)) {
uint pkt_len = PKTLEN(pnext);
for (pnext = pkt; pnext; pnext = pnext->next) {
uint pkt_len = pnext->len;
pkt_len += 3;
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
* 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)) {
err_ret = sdio_memcpy_toio(gInstance->func[func], addr,
((u8 *) PKTDATA(pnext)),
((u8 *) (pnext->data)),
pkt_len);
} else if (write) {
err_ret = sdio_memcpy_toio(gInstance->func[func], addr,
((u8 *) PKTDATA(pnext)),
((u8 *) (pnext->data)),
pkt_len);
} else if (fifo) {
err_ret = sdio_readsb(gInstance->func[func],
((u8 *) PKTDATA(pnext)),
((u8 *) (pnext->data)),
addr, pkt_len);
} else {
err_ret = sdio_memcpy_fromio(gInstance->func[func],
((u8 *) PKTDATA(pnext)),
((u8 *) (pnext->data)),
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
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,
u8 *buffer, void *pkt)
u8 *buffer, struct sk_buff *pkt)
{
SDIOH_API_RC Status;
void *mypkt = NULL;
struct sk_buff *mypkt = NULL;
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) {
sd_data(("%s: Creating new %s Packet, len=%d\n",
__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) {
sd_err(("%s: PKTGET failed: len %d\n",
sd_err(("%s: pkt_buf_get_skb failed: len %d\n",
__func__, buflen_u));
return SDIOH_API_RC_FAIL;
}
/* For a write, copy the buffer data into the packet. */
if (write)
bcopy(buffer, PKTDATA(mypkt), buflen_u);
bcopy(buffer, mypkt->data, buflen_u);
Status =
sdioh_request_packet(sd, fix_inc, write, func, addr, mypkt);
/* For a read, copy the packet data back to the buffer. */
if (!write)
bcopy(PKTDATA(mypkt), buffer, buflen_u);
bcopy(mypkt->data, buffer, buflen_u);
PKTFREE(sd->osh, mypkt, write ? true : false);
} else if (((u32) (PKTDATA(pkt)) & DMA_ALIGN_MASK) != 0) {
pkt_buf_free_skb(sd->osh, mypkt, write ? true : false);
} else if (((u32) (pkt->data) & DMA_ALIGN_MASK) != 0) {
/* Case 2: We have a packet, but it is unaligned. */
/* 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",
__func__, write ? "TX" : "RX", PKTLEN(pkt)));
mypkt = PKTGET(sd->osh, PKTLEN(pkt), write ? true : false);
__func__, write ? "TX" : "RX", pkt->len));
mypkt = pkt_buf_get_skb(sd->osh, pkt->len);
if (!mypkt) {
sd_err(("%s: PKTGET failed: len %d\n",
__func__, PKTLEN(pkt)));
sd_err(("%s: pkt_buf_get_skb failed: len %d\n",
__func__, pkt->len));
return SDIOH_API_RC_FAIL;
}
/* For a write, copy the buffer data into the packet. */
if (write)
bcopy(PKTDATA(pkt), PKTDATA(mypkt), PKTLEN(pkt));
bcopy(pkt->data, mypkt->data, pkt->len);
Status =
sdioh_request_packet(sd, fix_inc, write, func, addr, mypkt);
/* For a read, copy the packet data back to the buffer. */
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
it is aligned. */
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