Commit 9bff9dbd authored by David S. Miller's avatar David S. Miller
parents e2a6b852 d10c4ec8
...@@ -260,6 +260,9 @@ config ACPI_ASUS ...@@ -260,6 +260,9 @@ config ACPI_ASUS
config ACPI_TOSHIBA config ACPI_TOSHIBA
tristate "Toshiba Laptop Extras" tristate "Toshiba Laptop Extras"
depends on X86 depends on X86
select INPUT_POLLDEV
select NET
select RFKILL
select BACKLIGHT_CLASS_DEVICE select BACKLIGHT_CLASS_DEVICE
---help--- ---help---
This driver adds support for access to certain system settings This driver adds support for access to certain system settings
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
* *
* *
* Copyright (C) 2002-2004 John Belmonte * Copyright (C) 2002-2004 John Belmonte
* Copyright (C) 2008 Philip Langdale
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -33,7 +34,7 @@ ...@@ -33,7 +34,7 @@
* *
*/ */
#define TOSHIBA_ACPI_VERSION "0.18" #define TOSHIBA_ACPI_VERSION "0.19"
#define PROC_INTERFACE_VERSION 1 #define PROC_INTERFACE_VERSION 1
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -42,6 +43,9 @@ ...@@ -42,6 +43,9 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/backlight.h> #include <linux/backlight.h>
#include <linux/platform_device.h>
#include <linux/rfkill.h>
#include <linux/input-polldev.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -90,6 +94,7 @@ MODULE_LICENSE("GPL"); ...@@ -90,6 +94,7 @@ MODULE_LICENSE("GPL");
#define HCI_VIDEO_OUT 0x001c #define HCI_VIDEO_OUT 0x001c
#define HCI_HOTKEY_EVENT 0x001e #define HCI_HOTKEY_EVENT 0x001e
#define HCI_LCD_BRIGHTNESS 0x002a #define HCI_LCD_BRIGHTNESS 0x002a
#define HCI_WIRELESS 0x0056
/* field definitions */ /* field definitions */
#define HCI_LCD_BRIGHTNESS_BITS 3 #define HCI_LCD_BRIGHTNESS_BITS 3
...@@ -98,9 +103,14 @@ MODULE_LICENSE("GPL"); ...@@ -98,9 +103,14 @@ MODULE_LICENSE("GPL");
#define HCI_VIDEO_OUT_LCD 0x1 #define HCI_VIDEO_OUT_LCD 0x1
#define HCI_VIDEO_OUT_CRT 0x2 #define HCI_VIDEO_OUT_CRT 0x2
#define HCI_VIDEO_OUT_TV 0x4 #define HCI_VIDEO_OUT_TV 0x4
#define HCI_WIRELESS_KILL_SWITCH 0x01
#define HCI_WIRELESS_BT_PRESENT 0x0f
#define HCI_WIRELESS_BT_ATTACH 0x40
#define HCI_WIRELESS_BT_POWER 0x80
static const struct acpi_device_id toshiba_device_ids[] = { static const struct acpi_device_id toshiba_device_ids[] = {
{"TOS6200", 0}, {"TOS6200", 0},
{"TOS6208", 0},
{"TOS1900", 0}, {"TOS1900", 0},
{"", 0}, {"", 0},
}; };
...@@ -193,7 +203,7 @@ static acpi_status hci_raw(const u32 in[HCI_WORDS], u32 out[HCI_WORDS]) ...@@ -193,7 +203,7 @@ static acpi_status hci_raw(const u32 in[HCI_WORDS], u32 out[HCI_WORDS])
return status; return status;
} }
/* common hci tasks (get or set one value) /* common hci tasks (get or set one or two value)
* *
* In addition to the ACPI status, the HCI system returns a result which * In addition to the ACPI status, the HCI system returns a result which
* may be useful (such as "not supported"). * may be useful (such as "not supported").
...@@ -218,6 +228,152 @@ static acpi_status hci_read1(u32 reg, u32 * out1, u32 * result) ...@@ -218,6 +228,152 @@ static acpi_status hci_read1(u32 reg, u32 * out1, u32 * result)
return status; return status;
} }
static acpi_status hci_write2(u32 reg, u32 in1, u32 in2, u32 *result)
{
u32 in[HCI_WORDS] = { HCI_SET, reg, in1, in2, 0, 0 };
u32 out[HCI_WORDS];
acpi_status status = hci_raw(in, out);
*result = (status == AE_OK) ? out[0] : HCI_FAILURE;
return status;
}
static acpi_status hci_read2(u32 reg, u32 *out1, u32 *out2, u32 *result)
{
u32 in[HCI_WORDS] = { HCI_GET, reg, *out1, *out2, 0, 0 };
u32 out[HCI_WORDS];
acpi_status status = hci_raw(in, out);
*out1 = out[2];
*out2 = out[3];
*result = (status == AE_OK) ? out[0] : HCI_FAILURE;
return status;
}
struct toshiba_acpi_dev {
struct platform_device *p_dev;
struct rfkill *rfk_dev;
struct input_polled_dev *poll_dev;
const char *bt_name;
const char *rfk_name;
bool last_rfk_state;
struct mutex mutex;
};
static struct toshiba_acpi_dev toshiba_acpi = {
.bt_name = "Toshiba Bluetooth",
.rfk_name = "Toshiba RFKill Switch",
.last_rfk_state = false,
};
/* Bluetooth rfkill handlers */
static u32 hci_get_bt_present(bool *present)
{
u32 hci_result;
u32 value, value2;
value = 0;
value2 = 0;
hci_read2(HCI_WIRELESS, &value, &value2, &hci_result);
if (hci_result == HCI_SUCCESS)
*present = (value & HCI_WIRELESS_BT_PRESENT) ? true : false;
return hci_result;
}
static u32 hci_get_bt_on(bool *on)
{
u32 hci_result;
u32 value, value2;
value = 0;
value2 = 0x0001;
hci_read2(HCI_WIRELESS, &value, &value2, &hci_result);
if (hci_result == HCI_SUCCESS)
*on = (value & HCI_WIRELESS_BT_POWER) &&
(value & HCI_WIRELESS_BT_ATTACH);
return hci_result;
}
static u32 hci_get_radio_state(bool *radio_state)
{
u32 hci_result;
u32 value, value2;
value = 0;
value2 = 0x0001;
hci_read2(HCI_WIRELESS, &value, &value2, &hci_result);
*radio_state = value & HCI_WIRELESS_KILL_SWITCH;
return hci_result;
}
static int bt_rfkill_toggle_radio(void *data, enum rfkill_state state)
{
u32 result1, result2;
u32 value;
bool radio_state;
struct toshiba_acpi_dev *dev = data;
value = (state == RFKILL_STATE_UNBLOCKED);
if (hci_get_radio_state(&radio_state) != HCI_SUCCESS)
return -EFAULT;
switch (state) {
case RFKILL_STATE_UNBLOCKED:
if (!radio_state)
return -EPERM;
break;
case RFKILL_STATE_SOFT_BLOCKED:
break;
default:
return -EINVAL;
}
mutex_lock(&dev->mutex);
hci_write2(HCI_WIRELESS, value, HCI_WIRELESS_BT_POWER, &result1);
hci_write2(HCI_WIRELESS, value, HCI_WIRELESS_BT_ATTACH, &result2);
mutex_unlock(&dev->mutex);
if (result1 != HCI_SUCCESS || result2 != HCI_SUCCESS)
return -EFAULT;
return 0;
}
static void bt_poll_rfkill(struct input_polled_dev *poll_dev)
{
bool state_changed;
bool new_rfk_state;
bool value;
u32 hci_result;
struct toshiba_acpi_dev *dev = poll_dev->private;
hci_result = hci_get_radio_state(&value);
if (hci_result != HCI_SUCCESS)
return; /* Can't do anything useful */
new_rfk_state = value;
mutex_lock(&dev->mutex);
state_changed = new_rfk_state != dev->last_rfk_state;
dev->last_rfk_state = new_rfk_state;
mutex_unlock(&dev->mutex);
if (unlikely(state_changed)) {
rfkill_force_state(dev->rfk_dev,
new_rfk_state ?
RFKILL_STATE_SOFT_BLOCKED :
RFKILL_STATE_HARD_BLOCKED);
input_report_switch(poll_dev->input, SW_RFKILL_ALL,
new_rfk_state);
}
}
static struct proc_dir_entry *toshiba_proc_dir /*= 0*/ ; static struct proc_dir_entry *toshiba_proc_dir /*= 0*/ ;
static struct backlight_device *toshiba_backlight_device; static struct backlight_device *toshiba_backlight_device;
static int force_fan; static int force_fan;
...@@ -547,6 +703,14 @@ static struct backlight_ops toshiba_backlight_data = { ...@@ -547,6 +703,14 @@ static struct backlight_ops toshiba_backlight_data = {
static void toshiba_acpi_exit(void) static void toshiba_acpi_exit(void)
{ {
if (toshiba_acpi.poll_dev) {
input_unregister_polled_device(toshiba_acpi.poll_dev);
input_free_polled_device(toshiba_acpi.poll_dev);
}
if (toshiba_acpi.rfk_dev)
rfkill_unregister(toshiba_acpi.rfk_dev);
if (toshiba_backlight_device) if (toshiba_backlight_device)
backlight_device_unregister(toshiba_backlight_device); backlight_device_unregister(toshiba_backlight_device);
...@@ -555,6 +719,8 @@ static void toshiba_acpi_exit(void) ...@@ -555,6 +719,8 @@ static void toshiba_acpi_exit(void)
if (toshiba_proc_dir) if (toshiba_proc_dir)
remove_proc_entry(PROC_TOSHIBA, acpi_root_dir); remove_proc_entry(PROC_TOSHIBA, acpi_root_dir);
platform_device_unregister(toshiba_acpi.p_dev);
return; return;
} }
...@@ -562,6 +728,10 @@ static int __init toshiba_acpi_init(void) ...@@ -562,6 +728,10 @@ static int __init toshiba_acpi_init(void)
{ {
acpi_status status = AE_OK; acpi_status status = AE_OK;
u32 hci_result; u32 hci_result;
bool bt_present;
bool bt_on;
bool radio_on;
int ret = 0;
if (acpi_disabled) if (acpi_disabled)
return -ENODEV; return -ENODEV;
...@@ -578,6 +748,18 @@ static int __init toshiba_acpi_init(void) ...@@ -578,6 +748,18 @@ static int __init toshiba_acpi_init(void)
TOSHIBA_ACPI_VERSION); TOSHIBA_ACPI_VERSION);
printk(MY_INFO " HCI method: %s\n", method_hci); printk(MY_INFO " HCI method: %s\n", method_hci);
mutex_init(&toshiba_acpi.mutex);
toshiba_acpi.p_dev = platform_device_register_simple("toshiba_acpi",
-1, NULL, 0);
if (IS_ERR(toshiba_acpi.p_dev)) {
ret = PTR_ERR(toshiba_acpi.p_dev);
printk(MY_ERR "unable to register platform device\n");
toshiba_acpi.p_dev = NULL;
toshiba_acpi_exit();
return ret;
}
force_fan = 0; force_fan = 0;
key_event_valid = 0; key_event_valid = 0;
...@@ -586,19 +768,23 @@ static int __init toshiba_acpi_init(void) ...@@ -586,19 +768,23 @@ static int __init toshiba_acpi_init(void)
toshiba_proc_dir = proc_mkdir(PROC_TOSHIBA, acpi_root_dir); toshiba_proc_dir = proc_mkdir(PROC_TOSHIBA, acpi_root_dir);
if (!toshiba_proc_dir) { if (!toshiba_proc_dir) {
status = AE_ERROR; toshiba_acpi_exit();
return -ENODEV;
} else { } else {
toshiba_proc_dir->owner = THIS_MODULE; toshiba_proc_dir->owner = THIS_MODULE;
status = add_device(); status = add_device();
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status)) {
remove_proc_entry(PROC_TOSHIBA, acpi_root_dir); toshiba_acpi_exit();
return -ENODEV;
}
} }
toshiba_backlight_device = backlight_device_register("toshiba",NULL, toshiba_backlight_device = backlight_device_register("toshiba",
&toshiba_acpi.p_dev->dev,
NULL, NULL,
&toshiba_backlight_data); &toshiba_backlight_data);
if (IS_ERR(toshiba_backlight_device)) { if (IS_ERR(toshiba_backlight_device)) {
int ret = PTR_ERR(toshiba_backlight_device); ret = PTR_ERR(toshiba_backlight_device);
printk(KERN_ERR "Could not register toshiba backlight device\n"); printk(KERN_ERR "Could not register toshiba backlight device\n");
toshiba_backlight_device = NULL; toshiba_backlight_device = NULL;
...@@ -607,7 +793,66 @@ static int __init toshiba_acpi_init(void) ...@@ -607,7 +793,66 @@ static int __init toshiba_acpi_init(void)
} }
toshiba_backlight_device->props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1; toshiba_backlight_device->props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1;
return (ACPI_SUCCESS(status)) ? 0 : -ENODEV; /* Register rfkill switch for Bluetooth */
if (hci_get_bt_present(&bt_present) == HCI_SUCCESS && bt_present) {
toshiba_acpi.rfk_dev = rfkill_allocate(&toshiba_acpi.p_dev->dev,
RFKILL_TYPE_BLUETOOTH);
if (!toshiba_acpi.rfk_dev) {
printk(MY_ERR "unable to allocate rfkill device\n");
toshiba_acpi_exit();
return -ENOMEM;
}
toshiba_acpi.rfk_dev->name = toshiba_acpi.bt_name;
toshiba_acpi.rfk_dev->toggle_radio = bt_rfkill_toggle_radio;
toshiba_acpi.rfk_dev->user_claim_unsupported = 1;
toshiba_acpi.rfk_dev->data = &toshiba_acpi;
if (hci_get_bt_on(&bt_on) == HCI_SUCCESS && bt_on) {
toshiba_acpi.rfk_dev->state = RFKILL_STATE_UNBLOCKED;
} else if (hci_get_radio_state(&radio_on) == HCI_SUCCESS &&
radio_on) {
toshiba_acpi.rfk_dev->state = RFKILL_STATE_SOFT_BLOCKED;
} else {
toshiba_acpi.rfk_dev->state = RFKILL_STATE_HARD_BLOCKED;
}
ret = rfkill_register(toshiba_acpi.rfk_dev);
if (ret) {
printk(MY_ERR "unable to register rfkill device\n");
toshiba_acpi_exit();
return -ENOMEM;
}
}
/* Register input device for kill switch */
toshiba_acpi.poll_dev = input_allocate_polled_device();
if (!toshiba_acpi.poll_dev) {
printk(MY_ERR "unable to allocate kill-switch input device\n");
toshiba_acpi_exit();
return -ENOMEM;
}
toshiba_acpi.poll_dev->private = &toshiba_acpi;
toshiba_acpi.poll_dev->poll = bt_poll_rfkill;
toshiba_acpi.poll_dev->poll_interval = 1000; /* msecs */
toshiba_acpi.poll_dev->input->name = toshiba_acpi.rfk_name;
toshiba_acpi.poll_dev->input->id.bustype = BUS_HOST;
toshiba_acpi.poll_dev->input->id.vendor = 0x0930; /* Toshiba USB ID */
set_bit(EV_SW, toshiba_acpi.poll_dev->input->evbit);
set_bit(SW_RFKILL_ALL, toshiba_acpi.poll_dev->input->swbit);
input_report_switch(toshiba_acpi.poll_dev->input, SW_RFKILL_ALL, TRUE);
ret = input_register_polled_device(toshiba_acpi.poll_dev);
if (ret) {
printk(MY_ERR "unable to register kill-switch input device\n");
rfkill_free(toshiba_acpi.rfk_dev);
toshiba_acpi.rfk_dev = NULL;
toshiba_acpi_exit();
return ret;
}
return 0;
} }
module_init(toshiba_acpi_init); module_init(toshiba_acpi_init);
......
...@@ -1884,6 +1884,7 @@ static int __devinit adm8211_probe(struct pci_dev *pdev, ...@@ -1884,6 +1884,7 @@ static int __devinit adm8211_probe(struct pci_dev *pdev,
dev->extra_tx_headroom = sizeof(struct adm8211_tx_hdr); dev->extra_tx_headroom = sizeof(struct adm8211_tx_hdr);
/* dev->flags = IEEE80211_HW_RX_INCLUDES_FCS in promisc mode */ /* dev->flags = IEEE80211_HW_RX_INCLUDES_FCS in promisc mode */
dev->flags = IEEE80211_HW_SIGNAL_UNSPEC; dev->flags = IEEE80211_HW_SIGNAL_UNSPEC;
dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
dev->channel_change_time = 1000; dev->channel_change_time = 1000;
dev->max_signal = 100; /* FIXME: find better value */ dev->max_signal = 100; /* FIXME: find better value */
......
ath5k-y += base.o ath5k-y += caps.o
ath5k-y += hw.o
ath5k-y += initvals.o ath5k-y += initvals.o
ath5k-y += eeprom.o
ath5k-y += gpio.o
ath5k-y += desc.o
ath5k-y += dma.o
ath5k-y += qcu.o
ath5k-y += pcu.o
ath5k-y += phy.o ath5k-y += phy.o
ath5k-y += reset.o
ath5k-y += attach.o
ath5k-y += base.o
ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o
obj-$(CONFIG_ATH5K) += ath5k.o obj-$(CONFIG_ATH5K) += ath5k.o
This diff is collapsed.
/*
* Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
* Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
/*************************************\
* Attach/Detach Functions and helpers *
\*************************************/
#include <linux/pci.h>
#include "ath5k.h"
#include "reg.h"
#include "debug.h"
#include "base.h"
/**
* ath5k_hw_post - Power On Self Test helper function
*
* @ah: The &struct ath5k_hw
*/
static int ath5k_hw_post(struct ath5k_hw *ah)
{
int i, c;
u16 cur_reg;
u16 regs[2] = {AR5K_STA_ID0, AR5K_PHY(8)};
u32 var_pattern;
u32 static_pattern[4] = {
0x55555555, 0xaaaaaaaa,
0x66666666, 0x99999999
};
u32 init_val;
u32 cur_val;
for (c = 0; c < 2; c++) {
cur_reg = regs[c];
/* Save previous value */
init_val = ath5k_hw_reg_read(ah, cur_reg);
for (i = 0; i < 256; i++) {
var_pattern = i << 16 | i;
ath5k_hw_reg_write(ah, var_pattern, cur_reg);
cur_val = ath5k_hw_reg_read(ah, cur_reg);
if (cur_val != var_pattern) {
ATH5K_ERR(ah->ah_sc, "POST Failed !!!\n");
return -EAGAIN;
}
/* Found on ndiswrapper dumps */
var_pattern = 0x0039080f;
ath5k_hw_reg_write(ah, var_pattern, cur_reg);
}
for (i = 0; i < 4; i++) {
var_pattern = static_pattern[i];
ath5k_hw_reg_write(ah, var_pattern, cur_reg);
cur_val = ath5k_hw_reg_read(ah, cur_reg);
if (cur_val != var_pattern) {
ATH5K_ERR(ah->ah_sc, "POST Failed !!!\n");
return -EAGAIN;
}
/* Found on ndiswrapper dumps */
var_pattern = 0x003b080f;
ath5k_hw_reg_write(ah, var_pattern, cur_reg);
}
/* Restore previous value */
ath5k_hw_reg_write(ah, init_val, cur_reg);
}
return 0;
}
/**
* ath5k_hw_attach - Check if hw is supported and init the needed structs
*
* @sc: The &struct ath5k_softc we got from the driver's attach function
* @mac_version: The mac version id (check out ath5k.h) based on pci id
*
* Check if the device is supported, perform a POST and initialize the needed
* structs. Returns -ENOMEM if we don't have memory for the needed structs,
* -ENODEV if the device is not supported or prints an error msg if something
* else went wrong.
*/
struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
{
struct ath5k_hw *ah;
struct pci_dev *pdev = sc->pdev;
u8 mac[ETH_ALEN];
int ret;
u32 srev;
/*If we passed the test malloc a ath5k_hw struct*/
ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL);
if (ah == NULL) {
ret = -ENOMEM;
ATH5K_ERR(sc, "out of memory\n");
goto err;
}
ah->ah_sc = sc;
ah->ah_iobase = sc->iobase;
/*
* HW information
*/
ah->ah_op_mode = IEEE80211_IF_TYPE_STA;
ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT;
ah->ah_turbo = false;
ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
ah->ah_imr = 0;
ah->ah_atim_window = 0;
ah->ah_aifs = AR5K_TUNE_AIFS;
ah->ah_cw_min = AR5K_TUNE_CWMIN;
ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY;
ah->ah_software_retry = false;
ah->ah_ant_diversity = AR5K_TUNE_ANT_DIVERSITY;
/*
* Set the mac revision based on the pci id
*/
ah->ah_version = mac_version;
/*Fill the ath5k_hw struct with the needed functions*/
ret = ath5k_hw_init_desc_functions(ah);
if (ret)
goto err_free;
/* Bring device out of sleep and reset it's units */
ret = ath5k_hw_nic_wakeup(ah, CHANNEL_B, true);
if (ret)
goto err_free;
/* Get MAC, PHY and RADIO revisions */
srev = ath5k_hw_reg_read(ah, AR5K_SREV);
ah->ah_mac_srev = srev;
ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER);
ah->ah_mac_revision = AR5K_REG_MS(srev, AR5K_SREV_REV);
ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID) &
0xffffffff;
ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah,
CHANNEL_5GHZ);
if (ah->ah_version == AR5K_AR5210)
ah->ah_radio_2ghz_revision = 0;
else
ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
CHANNEL_2GHZ);
/* Return on unsuported chips (unsupported eeprom etc) */
if ((srev >= AR5K_SREV_VER_AR5416) &&
(srev < AR5K_SREV_VER_AR2425)) {
ATH5K_ERR(sc, "Device not yet supported.\n");
ret = -ENODEV;
goto err_free;
} else if (srev == AR5K_SREV_VER_AR2425) {
ATH5K_WARN(sc, "Support for RF2425 is under development.\n");
}
/* Identify single chip solutions */
if (((srev <= AR5K_SREV_VER_AR5414) &&
(srev >= AR5K_SREV_VER_AR2413)) ||
(srev == AR5K_SREV_VER_AR2425)) {
ah->ah_single_chip = true;
} else {
ah->ah_single_chip = false;
}
/* Single chip radio */
if (ah->ah_radio_2ghz_revision == ah->ah_radio_5ghz_revision)
ah->ah_radio_2ghz_revision = 0;
/* Identify the radio chip*/
if (ah->ah_version == AR5K_AR5210) {
ah->ah_radio = AR5K_RF5110;
/*
* Register returns 0x0/0x04 for radio revision
* so ath5k_hw_radio_revision doesn't parse the value
* correctly. For now we are based on mac's srev to
* identify RF2425 radio.
*/
} else if (srev == AR5K_SREV_VER_AR2425) {
ah->ah_radio = AR5K_RF2425;
ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2425;
} else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112) {
ah->ah_radio = AR5K_RF5111;
ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5111;
} else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC0) {
ah->ah_radio = AR5K_RF5112;
ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112;
} else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC1) {
ah->ah_radio = AR5K_RF2413;
ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2413;
} else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC2) {
ah->ah_radio = AR5K_RF5413;
ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413;
} else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5133) {
/* AR5424 */
if (srev >= AR5K_SREV_VER_AR5424) {
ah->ah_radio = AR5K_RF5413;
ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413;
/* AR2424 */
} else {
ah->ah_radio = AR5K_RF2413; /* For testing */
ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2413;
}
}
ah->ah_phy = AR5K_PHY(0);
/*
* Write PCI-E power save settings
*/
if ((ah->ah_version == AR5K_AR5212) && (pdev->is_pcie)) {
ath5k_hw_reg_write(ah, 0x9248fc00, 0x4080);
ath5k_hw_reg_write(ah, 0x24924924, 0x4080);
ath5k_hw_reg_write(ah, 0x28000039, 0x4080);
ath5k_hw_reg_write(ah, 0x53160824, 0x4080);
ath5k_hw_reg_write(ah, 0xe5980579, 0x4080);
ath5k_hw_reg_write(ah, 0x001defff, 0x4080);
ath5k_hw_reg_write(ah, 0x1aaabe40, 0x4080);
ath5k_hw_reg_write(ah, 0xbe105554, 0x4080);
ath5k_hw_reg_write(ah, 0x000e3007, 0x4080);
ath5k_hw_reg_write(ah, 0x00000000, 0x4084);
}
/*
* POST
*/
ret = ath5k_hw_post(ah);
if (ret)
goto err_free;
/* Write AR5K_PCICFG_UNK on 2112B and later chips */
if (ah->ah_radio_5ghz_revision > AR5K_SREV_RAD_2112B ||
srev > AR5K_SREV_VER_AR2413) {
ath5k_hw_reg_write(ah, AR5K_PCICFG_UNK, AR5K_PCICFG);
}
/*
* Get card capabilities, values, ...
*/
ret = ath5k_eeprom_init(ah);
if (ret) {
ATH5K_ERR(sc, "unable to init EEPROM\n");
goto err_free;
}
/* Get misc capabilities */
ret = ath5k_hw_set_capabilities(ah);
if (ret) {
ATH5K_ERR(sc, "unable to get device capabilities: 0x%04x\n",
sc->pdev->device);
goto err_free;
}
/* Get MAC address */
ret = ath5k_eeprom_read_mac(ah, mac);
if (ret) {
ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n",
sc->pdev->device);
goto err_free;
}
ath5k_hw_set_lladdr(ah, mac);
/* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */
memset(ah->ah_bssid, 0xff, ETH_ALEN);
ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
ath5k_hw_set_opmode(ah);
ath5k_hw_set_rfgain_opt(ah);
return ah;
err_free:
kfree(ah);
err:
return ERR_PTR(ret);
}
/**
* ath5k_hw_detach - Free the ath5k_hw struct
*
* @ah: The &struct ath5k_hw
*/
void ath5k_hw_detach(struct ath5k_hw *ah)
{
ATH5K_TRACE(ah->ah_sc);
__set_bit(ATH_STAT_INVALID, ah->ah_sc->status);
if (ah->ah_rf_banks != NULL)
kfree(ah->ah_rf_banks);
/* assume interrupts are down */
kfree(ah);
}
...@@ -485,6 +485,12 @@ ath5k_pci_probe(struct pci_dev *pdev, ...@@ -485,6 +485,12 @@ ath5k_pci_probe(struct pci_dev *pdev,
hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_NOISE_DBM; IEEE80211_HW_NOISE_DBM;
hw->wiphy->interface_modes =
BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_ADHOC) |
BIT(NL80211_IFTYPE_MESH_POINT);
hw->extra_tx_headroom = 2; hw->extra_tx_headroom = 2;
hw->channel_change_time = 5000; hw->channel_change_time = 5000;
sc = hw->priv; sc = hw->priv;
...@@ -707,7 +713,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) ...@@ -707,7 +713,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
* return false w/o doing anything. MAC's that do * return false w/o doing anything. MAC's that do
* support it will return true w/o doing anything. * support it will return true w/o doing anything.
*/ */
ret = ah->ah_setup_xtx_desc(ah, NULL, 0, 0, 0, 0, 0, 0); ret = ah->ah_setup_mrr_tx_desc(ah, NULL, 0, 0, 0, 0, 0, 0);
if (ret < 0) if (ret < 0)
goto err; goto err;
if (ret > 0) if (ret > 0)
...@@ -1137,7 +1143,7 @@ ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) ...@@ -1137,7 +1143,7 @@ ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
ds = bf->desc; ds = bf->desc;
ds->ds_link = bf->daddr; /* link to self */ ds->ds_link = bf->daddr; /* link to self */
ds->ds_data = bf->skbaddr; ds->ds_data = bf->skbaddr;
ath5k_hw_setup_rx_desc(ah, ds, ah->ah_setup_rx_desc(ah, ds,
skb_tailroom(skb), /* buffer size */ skb_tailroom(skb), /* buffer size */
0); 0);
...@@ -1188,12 +1194,12 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) ...@@ -1188,12 +1194,12 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
list_add_tail(&bf->list, &txq->q); list_add_tail(&bf->list, &txq->q);
sc->tx_stats[txq->qnum].len++; sc->tx_stats[txq->qnum].len++;
if (txq->link == NULL) /* is this first packet? */ if (txq->link == NULL) /* is this first packet? */
ath5k_hw_put_tx_buf(ah, txq->qnum, bf->daddr); ath5k_hw_set_txdp(ah, txq->qnum, bf->daddr);
else /* no, so only link it */ else /* no, so only link it */
*txq->link = bf->daddr; *txq->link = bf->daddr;
txq->link = &ds->ds_link; txq->link = &ds->ds_link;
ath5k_hw_tx_start(ah, txq->qnum); ath5k_hw_start_tx_dma(ah, txq->qnum);
mmiowb(); mmiowb();
spin_unlock_bh(&txq->lock); spin_unlock_bh(&txq->lock);
...@@ -1393,7 +1399,7 @@ ath5k_beaconq_config(struct ath5k_softc *sc) ...@@ -1393,7 +1399,7 @@ ath5k_beaconq_config(struct ath5k_softc *sc)
"beacon queueprops tqi_aifs:%d tqi_cw_min:%d tqi_cw_max:%d\n", "beacon queueprops tqi_aifs:%d tqi_cw_min:%d tqi_cw_max:%d\n",
qi.tqi_aifs, qi.tqi_cw_min, qi.tqi_cw_max); qi.tqi_aifs, qi.tqi_cw_min, qi.tqi_cw_max);
ret = ath5k_hw_setup_tx_queueprops(ah, sc->bhalq, &qi); ret = ath5k_hw_set_tx_queueprops(ah, sc->bhalq, &qi);
if (ret) { if (ret) {
ATH5K_ERR(sc, "%s: unable to update parameters for beacon " ATH5K_ERR(sc, "%s: unable to update parameters for beacon "
"hardware queue!\n", __func__); "hardware queue!\n", __func__);
...@@ -1442,14 +1448,14 @@ ath5k_txq_cleanup(struct ath5k_softc *sc) ...@@ -1442,14 +1448,14 @@ ath5k_txq_cleanup(struct ath5k_softc *sc)
/* don't touch the hardware if marked invalid */ /* don't touch the hardware if marked invalid */
ath5k_hw_stop_tx_dma(ah, sc->bhalq); ath5k_hw_stop_tx_dma(ah, sc->bhalq);
ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "beacon queue %x\n", ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "beacon queue %x\n",
ath5k_hw_get_tx_buf(ah, sc->bhalq)); ath5k_hw_get_txdp(ah, sc->bhalq));
for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) for (i = 0; i < ARRAY_SIZE(sc->txqs); i++)
if (sc->txqs[i].setup) { if (sc->txqs[i].setup) {
ath5k_hw_stop_tx_dma(ah, sc->txqs[i].qnum); ath5k_hw_stop_tx_dma(ah, sc->txqs[i].qnum);
ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "txq [%u] %x, " ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "txq [%u] %x, "
"link %p\n", "link %p\n",
sc->txqs[i].qnum, sc->txqs[i].qnum,
ath5k_hw_get_tx_buf(ah, ath5k_hw_get_txdp(ah,
sc->txqs[i].qnum), sc->txqs[i].qnum),
sc->txqs[i].link); sc->txqs[i].link);
} }
...@@ -1509,8 +1515,8 @@ ath5k_rx_start(struct ath5k_softc *sc) ...@@ -1509,8 +1515,8 @@ ath5k_rx_start(struct ath5k_softc *sc)
bf = list_first_entry(&sc->rxbuf, struct ath5k_buf, list); bf = list_first_entry(&sc->rxbuf, struct ath5k_buf, list);
spin_unlock_bh(&sc->rxbuflock); spin_unlock_bh(&sc->rxbuflock);
ath5k_hw_put_rx_buf(ah, bf->daddr); ath5k_hw_set_rxdp(ah, bf->daddr);
ath5k_hw_start_rx(ah); /* enable recv descriptors */ ath5k_hw_start_rx_dma(ah); /* enable recv descriptors */
ath5k_mode_setup(sc); /* set filters, etc. */ ath5k_mode_setup(sc); /* set filters, etc. */
ath5k_hw_start_rx_pcu(ah); /* re-enable PCU/DMA engine */ ath5k_hw_start_rx_pcu(ah); /* re-enable PCU/DMA engine */
...@@ -1527,7 +1533,7 @@ ath5k_rx_stop(struct ath5k_softc *sc) ...@@ -1527,7 +1533,7 @@ ath5k_rx_stop(struct ath5k_softc *sc)
{ {
struct ath5k_hw *ah = sc->ah; struct ath5k_hw *ah = sc->ah;
ath5k_hw_stop_pcu_recv(ah); /* disable PCU */ ath5k_hw_stop_rx_pcu(ah); /* disable PCU */
ath5k_hw_set_rx_filter(ah, 0); /* clear recv filter */ ath5k_hw_set_rx_filter(ah, 0); /* clear recv filter */
ath5k_hw_stop_rx_dma(ah); /* disable DMA engine */ ath5k_hw_stop_rx_dma(ah); /* disable DMA engine */
...@@ -1976,8 +1982,8 @@ ath5k_beacon_send(struct ath5k_softc *sc) ...@@ -1976,8 +1982,8 @@ ath5k_beacon_send(struct ath5k_softc *sc)
/* NB: hw still stops DMA, so proceed */ /* NB: hw still stops DMA, so proceed */
} }
ath5k_hw_put_tx_buf(ah, sc->bhalq, bf->daddr); ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr);
ath5k_hw_tx_start(ah, sc->bhalq); ath5k_hw_start_tx_dma(ah, sc->bhalq);
ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n", ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n",
sc->bhalq, (unsigned long long)bf->daddr, bf->desc); sc->bhalq, (unsigned long long)bf->daddr, bf->desc);
...@@ -2106,7 +2112,7 @@ ath5k_beacon_config(struct ath5k_softc *sc) ...@@ -2106,7 +2112,7 @@ ath5k_beacon_config(struct ath5k_softc *sc)
{ {
struct ath5k_hw *ah = sc->ah; struct ath5k_hw *ah = sc->ah;
ath5k_hw_set_intr(ah, 0); ath5k_hw_set_imr(ah, 0);
sc->bmisscount = 0; sc->bmisscount = 0;
sc->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA); sc->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA);
...@@ -2132,7 +2138,7 @@ ath5k_beacon_config(struct ath5k_softc *sc) ...@@ -2132,7 +2138,7 @@ ath5k_beacon_config(struct ath5k_softc *sc)
} }
/* TODO else AP */ /* TODO else AP */
ath5k_hw_set_intr(ah, sc->imask); ath5k_hw_set_imr(ah, sc->imask);
} }
...@@ -2211,7 +2217,7 @@ ath5k_stop_locked(struct ath5k_softc *sc) ...@@ -2211,7 +2217,7 @@ ath5k_stop_locked(struct ath5k_softc *sc)
if (!test_bit(ATH_STAT_INVALID, sc->status)) { if (!test_bit(ATH_STAT_INVALID, sc->status)) {
ath5k_led_off(sc); ath5k_led_off(sc);
ath5k_hw_set_intr(ah, 0); ath5k_hw_set_imr(ah, 0);
synchronize_irq(sc->pdev->irq); synchronize_irq(sc->pdev->irq);
} }
ath5k_txq_cleanup(sc); ath5k_txq_cleanup(sc);
...@@ -2604,7 +2610,7 @@ ath5k_reset(struct ath5k_softc *sc, bool stop, bool change_channel) ...@@ -2604,7 +2610,7 @@ ath5k_reset(struct ath5k_softc *sc, bool stop, bool change_channel)
ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n"); ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n");
if (stop) { if (stop) {
ath5k_hw_set_intr(ah, 0); ath5k_hw_set_imr(ah, 0);
ath5k_txq_cleanup(sc); ath5k_txq_cleanup(sc);
ath5k_rx_stop(sc); ath5k_rx_stop(sc);
} }
......
/*
* Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
* Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
* Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
/**************\
* Capabilities *
\**************/
#include "ath5k.h"
#include "reg.h"
#include "debug.h"
#include "base.h"
/*
* Fill the capabilities struct
* TODO: Merge this with EEPROM code when we are done with it
*/
int ath5k_hw_set_capabilities(struct ath5k_hw *ah)
{
u16 ee_header;
ATH5K_TRACE(ah->ah_sc);
/* Capabilities stored in the EEPROM */
ee_header = ah->ah_capabilities.cap_eeprom.ee_header;
if (ah->ah_version == AR5K_AR5210) {
/*
* Set radio capabilities
* (The AR5110 only supports the middle 5GHz band)
*/
ah->ah_capabilities.cap_range.range_5ghz_min = 5120;
ah->ah_capabilities.cap_range.range_5ghz_max = 5430;
ah->ah_capabilities.cap_range.range_2ghz_min = 0;
ah->ah_capabilities.cap_range.range_2ghz_max = 0;
/* Set supported modes */
__set_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode);
__set_bit(AR5K_MODE_11A_TURBO, ah->ah_capabilities.cap_mode);
} else {
/*
* XXX The tranceiver supports frequencies from 4920 to 6100GHz
* XXX and from 2312 to 2732GHz. There are problems with the
* XXX current ieee80211 implementation because the IEEE
* XXX channel mapping does not support negative channel
* XXX numbers (2312MHz is channel -19). Of course, this
* XXX doesn't matter because these channels are out of range
* XXX but some regulation domains like MKK (Japan) will
* XXX support frequencies somewhere around 4.8GHz.
*/
/*
* Set radio capabilities
*/
if (AR5K_EEPROM_HDR_11A(ee_header)) {
/* 4920 */
ah->ah_capabilities.cap_range.range_5ghz_min = 5005;
ah->ah_capabilities.cap_range.range_5ghz_max = 6100;
/* Set supported modes */
__set_bit(AR5K_MODE_11A,
ah->ah_capabilities.cap_mode);
__set_bit(AR5K_MODE_11A_TURBO,
ah->ah_capabilities.cap_mode);
if (ah->ah_version == AR5K_AR5212)
__set_bit(AR5K_MODE_11G_TURBO,
ah->ah_capabilities.cap_mode);
}
/* Enable 802.11b if a 2GHz capable radio (2111/5112) is
* connected */
if (AR5K_EEPROM_HDR_11B(ee_header) ||
AR5K_EEPROM_HDR_11G(ee_header)) {
/* 2312 */
ah->ah_capabilities.cap_range.range_2ghz_min = 2412;
ah->ah_capabilities.cap_range.range_2ghz_max = 2732;
if (AR5K_EEPROM_HDR_11B(ee_header))
__set_bit(AR5K_MODE_11B,
ah->ah_capabilities.cap_mode);
if (AR5K_EEPROM_HDR_11G(ee_header))
__set_bit(AR5K_MODE_11G,
ah->ah_capabilities.cap_mode);
}
}
/* GPIO */
ah->ah_gpio_npins = AR5K_NUM_GPIO;
/* Set number of supported TX queues */
if (ah->ah_version == AR5K_AR5210)
ah->ah_capabilities.cap_queues.q_tx_num =
AR5K_NUM_TX_QUEUES_NOQCU;
else
ah->ah_capabilities.cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES;
return 0;
}
/* Main function used by the driver part to check caps */
int ath5k_hw_get_capability(struct ath5k_hw *ah,
enum ath5k_capability_type cap_type,
u32 capability, u32 *result)
{
ATH5K_TRACE(ah->ah_sc);
switch (cap_type) {
case AR5K_CAP_NUM_TXQUEUES:
if (result) {
if (ah->ah_version == AR5K_AR5210)
*result = AR5K_NUM_TX_QUEUES_NOQCU;
else
*result = AR5K_NUM_TX_QUEUES;
goto yes;
}
case AR5K_CAP_VEOL:
goto yes;
case AR5K_CAP_COMPRESSION:
if (ah->ah_version == AR5K_AR5212)
goto yes;
else
goto no;
case AR5K_CAP_BURST:
goto yes;
case AR5K_CAP_TPC:
goto yes;
case AR5K_CAP_BSSIDMASK:
if (ah->ah_version == AR5K_AR5212)
goto yes;
else
goto no;
case AR5K_CAP_XR:
if (ah->ah_version == AR5K_AR5212)
goto yes;
else
goto no;
default:
goto no;
}
no:
return -EINVAL;
yes:
return 0;
}
/*
* TODO: Following functions should be part of a new function
* set_capability
*/
int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid,
u16 assoc_id)
{
ATH5K_TRACE(ah->ah_sc);
if (ah->ah_version == AR5K_AR5210) {
AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA);
return 0;
}
return -EIO;
}
int ath5k_hw_disable_pspoll(struct ath5k_hw *ah)
{
ATH5K_TRACE(ah->ah_sc);
if (ah->ah_version == AR5K_AR5210) {
AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1,
AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA);
return 0;
}
return -EIO;
}
...@@ -58,8 +58,8 @@ ...@@ -58,8 +58,8 @@
* THE POSSIBILITY OF SUCH DAMAGES. * THE POSSIBILITY OF SUCH DAMAGES.
*/ */
#include "debug.h"
#include "base.h" #include "base.h"
#include "debug.h"
static unsigned int ath5k_debug; static unsigned int ath5k_debug;
module_param_named(debug, ath5k_debug, uint, 0); module_param_named(debug, ath5k_debug, uint, 0);
...@@ -525,7 +525,7 @@ ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah) ...@@ -525,7 +525,7 @@ ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah)
return; return;
printk(KERN_DEBUG "rx queue %x, link %p\n", printk(KERN_DEBUG "rx queue %x, link %p\n",
ath5k_hw_get_rx_buf(ah), sc->rxlink); ath5k_hw_get_rxdp(ah), sc->rxlink);
spin_lock_bh(&sc->rxbuflock); spin_lock_bh(&sc->rxbuflock);
list_for_each_entry(bf, &sc->rxbuf, list) { list_for_each_entry(bf, &sc->rxbuf, list) {
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
* Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
/*
* Common ar5xxx EEPROM data offsets (set these on AR5K_EEPROM_BASE)
*/
#define AR5K_EEPROM_MAGIC 0x003d /* EEPROM Magic number */
#define AR5K_EEPROM_MAGIC_VALUE 0x5aa5 /* Default - found on EEPROM */
#define AR5K_EEPROM_MAGIC_5212 0x0000145c /* 5212 */
#define AR5K_EEPROM_MAGIC_5211 0x0000145b /* 5211 */
#define AR5K_EEPROM_MAGIC_5210 0x0000145a /* 5210 */
#define AR5K_EEPROM_PROTECT 0x003f /* EEPROM protect status */
#define AR5K_EEPROM_PROTECT_RD_0_31 0x0001 /* Read protection bit for offsets 0x0 - 0x1f */
#define AR5K_EEPROM_PROTECT_WR_0_31 0x0002 /* Write protection bit for offsets 0x0 - 0x1f */
#define AR5K_EEPROM_PROTECT_RD_32_63 0x0004 /* 0x20 - 0x3f */
#define AR5K_EEPROM_PROTECT_WR_32_63 0x0008
#define AR5K_EEPROM_PROTECT_RD_64_127 0x0010 /* 0x40 - 0x7f */
#define AR5K_EEPROM_PROTECT_WR_64_127 0x0020
#define AR5K_EEPROM_PROTECT_RD_128_191 0x0040 /* 0x80 - 0xbf (regdom) */
#define AR5K_EEPROM_PROTECT_WR_128_191 0x0080
#define AR5K_EEPROM_PROTECT_RD_192_207 0x0100 /* 0xc0 - 0xcf */
#define AR5K_EEPROM_PROTECT_WR_192_207 0x0200
#define AR5K_EEPROM_PROTECT_RD_208_223 0x0400 /* 0xd0 - 0xdf */
#define AR5K_EEPROM_PROTECT_WR_208_223 0x0800
#define AR5K_EEPROM_PROTECT_RD_224_239 0x1000 /* 0xe0 - 0xef */
#define AR5K_EEPROM_PROTECT_WR_224_239 0x2000
#define AR5K_EEPROM_PROTECT_RD_240_255 0x4000 /* 0xf0 - 0xff */
#define AR5K_EEPROM_PROTECT_WR_240_255 0x8000
#define AR5K_EEPROM_REG_DOMAIN 0x00bf /* EEPROM regdom */
#define AR5K_EEPROM_INFO_BASE 0x00c0 /* EEPROM header */
#define AR5K_EEPROM_INFO_MAX (0x400 - AR5K_EEPROM_INFO_BASE)
#define AR5K_EEPROM_INFO_CKSUM 0xffff
#define AR5K_EEPROM_INFO(_n) (AR5K_EEPROM_INFO_BASE + (_n))
#define AR5K_EEPROM_VERSION AR5K_EEPROM_INFO(1) /* EEPROM Version */
#define AR5K_EEPROM_VERSION_3_0 0x3000 /* No idea what's going on before this version */
#define AR5K_EEPROM_VERSION_3_1 0x3001 /* ob/db values for 2Ghz (ar5211_rfregs) */
#define AR5K_EEPROM_VERSION_3_2 0x3002 /* different frequency representation (eeprom_bin2freq) */
#define AR5K_EEPROM_VERSION_3_3 0x3003 /* offsets changed, has 32 CTLs (see below) and ee_false_detect (eeprom_read_modes) */
#define AR5K_EEPROM_VERSION_3_4 0x3004 /* has ee_i_gain ee_cck_ofdm_power_delta (eeprom_read_modes) */
#define AR5K_EEPROM_VERSION_4_0 0x4000 /* has ee_misc*, ee_cal_pier, ee_turbo_max_power and ee_xr_power (eeprom_init) */
#define AR5K_EEPROM_VERSION_4_1 0x4001 /* has ee_margin_tx_rx (eeprom_init) */
#define AR5K_EEPROM_VERSION_4_2 0x4002 /* has ee_cck_ofdm_gain_delta (eeprom_init) */
#define AR5K_EEPROM_VERSION_4_3 0x4003
#define AR5K_EEPROM_VERSION_4_4 0x4004
#define AR5K_EEPROM_VERSION_4_5 0x4005
#define AR5K_EEPROM_VERSION_4_6 0x4006 /* has ee_scaled_cck_delta */
#define AR5K_EEPROM_VERSION_4_7 0x4007
#define AR5K_EEPROM_MODE_11A 0
#define AR5K_EEPROM_MODE_11B 1
#define AR5K_EEPROM_MODE_11G 2
#define AR5K_EEPROM_HDR AR5K_EEPROM_INFO(2) /* Header that contains the device caps */
#define AR5K_EEPROM_HDR_11A(_v) (((_v) >> AR5K_EEPROM_MODE_11A) & 0x1)
#define AR5K_EEPROM_HDR_11B(_v) (((_v) >> AR5K_EEPROM_MODE_11B) & 0x1)
#define AR5K_EEPROM_HDR_11G(_v) (((_v) >> AR5K_EEPROM_MODE_11G) & 0x1)
#define AR5K_EEPROM_HDR_T_2GHZ_DIS(_v) (((_v) >> 3) & 0x1) /* Disable turbo for 2Ghz (?) */
#define AR5K_EEPROM_HDR_T_5GHZ_DBM(_v) (((_v) >> 4) & 0x7f) /* Max turbo power for a/XR mode (eeprom_init) */
#define AR5K_EEPROM_HDR_DEVICE(_v) (((_v) >> 11) & 0x7)
#define AR5K_EEPROM_HDR_T_5GHZ_DIS(_v) (((_v) >> 15) & 0x1) /* Disable turbo for 5Ghz (?) */
#define AR5K_EEPROM_HDR_RFKILL(_v) (((_v) >> 14) & 0x1) /* Device has RFKill support */
#define AR5K_EEPROM_RFKILL_GPIO_SEL 0x0000001c
#define AR5K_EEPROM_RFKILL_GPIO_SEL_S 2
#define AR5K_EEPROM_RFKILL_POLARITY 0x00000002
#define AR5K_EEPROM_RFKILL_POLARITY_S 1
/* Newer EEPROMs are using a different offset */
#define AR5K_EEPROM_OFF(_v, _v3_0, _v3_3) \
(((_v) >= AR5K_EEPROM_VERSION_3_3) ? _v3_3 : _v3_0)
#define AR5K_EEPROM_ANT_GAIN(_v) AR5K_EEPROM_OFF(_v, 0x00c4, 0x00c3)
#define AR5K_EEPROM_ANT_GAIN_5GHZ(_v) ((int8_t)(((_v) >> 8) & 0xff))
#define AR5K_EEPROM_ANT_GAIN_2GHZ(_v) ((int8_t)((_v) & 0xff))
/* calibration settings */
#define AR5K_EEPROM_MODES_11A(_v) AR5K_EEPROM_OFF(_v, 0x00c5, 0x00d4)
#define AR5K_EEPROM_MODES_11B(_v) AR5K_EEPROM_OFF(_v, 0x00d0, 0x00f2)
#define AR5K_EEPROM_MODES_11G(_v) AR5K_EEPROM_OFF(_v, 0x00da, 0x010d)
#define AR5K_EEPROM_CTL(_v) AR5K_EEPROM_OFF(_v, 0x00e4, 0x0128) /* Conformance test limits */
/* [3.1 - 3.3] */
#define AR5K_EEPROM_OBDB0_2GHZ 0x00ec
#define AR5K_EEPROM_OBDB1_2GHZ 0x00ed
/* Misc values available since EEPROM 4.0 */
#define AR5K_EEPROM_MISC0 0x00c4
#define AR5K_EEPROM_EARSTART(_v) ((_v) & 0xfff)
#define AR5K_EEPROM_EEMAP(_v) (((_v) >> 14) & 0x3)
#define AR5K_EEPROM_MISC1 0x00c5
#define AR5K_EEPROM_TARGET_PWRSTART(_v) ((_v) & 0xfff)
#define AR5K_EEPROM_HAS32KHZCRYSTAL(_v) (((_v) >> 14) & 0x1)
/* Some EEPROM defines */
#define AR5K_EEPROM_EEP_SCALE 100
#define AR5K_EEPROM_EEP_DELTA 10
#define AR5K_EEPROM_N_MODES 3
#define AR5K_EEPROM_N_5GHZ_CHAN 10
#define AR5K_EEPROM_N_2GHZ_CHAN 3
#define AR5K_EEPROM_MAX_CHAN 10
#define AR5K_EEPROM_N_PCDAC 11
#define AR5K_EEPROM_N_TEST_FREQ 8
#define AR5K_EEPROM_N_EDGES 8
#define AR5K_EEPROM_N_INTERCEPTS 11
#define AR5K_EEPROM_FREQ_M(_v) AR5K_EEPROM_OFF(_v, 0x7f, 0xff)
#define AR5K_EEPROM_PCDAC_M 0x3f
#define AR5K_EEPROM_PCDAC_START 1
#define AR5K_EEPROM_PCDAC_STOP 63
#define AR5K_EEPROM_PCDAC_STEP 1
#define AR5K_EEPROM_NON_EDGE_M 0x40
#define AR5K_EEPROM_CHANNEL_POWER 8
#define AR5K_EEPROM_N_OBDB 4
#define AR5K_EEPROM_OBDB_DIS 0xffff
#define AR5K_EEPROM_CHANNEL_DIS 0xff
#define AR5K_EEPROM_SCALE_OC_DELTA(_x) (((_x) * 2) / 10)
#define AR5K_EEPROM_N_CTLS(_v) AR5K_EEPROM_OFF(_v, 16, 32)
#define AR5K_EEPROM_MAX_CTLS 32
#define AR5K_EEPROM_N_XPD_PER_CHANNEL 4
#define AR5K_EEPROM_N_XPD0_POINTS 4
#define AR5K_EEPROM_N_XPD3_POINTS 3
#define AR5K_EEPROM_N_INTERCEPT_10_2GHZ 35
#define AR5K_EEPROM_N_INTERCEPT_10_5GHZ 55
#define AR5K_EEPROM_POWER_M 0x3f
#define AR5K_EEPROM_POWER_MIN 0
#define AR5K_EEPROM_POWER_MAX 3150
#define AR5K_EEPROM_POWER_STEP 50
#define AR5K_EEPROM_POWER_TABLE_SIZE 64
#define AR5K_EEPROM_N_POWER_LOC_11B 4
#define AR5K_EEPROM_N_POWER_LOC_11G 6
#define AR5K_EEPROM_I_GAIN 10
#define AR5K_EEPROM_CCK_OFDM_DELTA 15
#define AR5K_EEPROM_N_IQ_CAL 2
#define AR5K_EEPROM_READ(_o, _v) do { \
ret = ath5k_hw_eeprom_read(ah, (_o), &(_v)); \
if (ret) \
return ret; \
} while (0)
#define AR5K_EEPROM_READ_HDR(_o, _v) \
AR5K_EEPROM_READ(_o, ah->ah_capabilities.cap_eeprom._v); \
/* Struct to hold EEPROM calibration data */
struct ath5k_eeprom_info {
u16 ee_magic;
u16 ee_protect;
u16 ee_regdomain;
u16 ee_version;
u16 ee_header;
u16 ee_ant_gain;
u16 ee_misc0;
u16 ee_misc1;
u16 ee_cck_ofdm_gain_delta;
u16 ee_cck_ofdm_power_delta;
u16 ee_scaled_cck_delta;
/* Used for tx thermal adjustment (eeprom_init, rfregs) */
u16 ee_tx_clip;
u16 ee_pwd_84;
u16 ee_pwd_90;
u16 ee_gain_select;
/* RF Calibration settings (reset, rfregs) */
u16 ee_i_cal[AR5K_EEPROM_N_MODES];
u16 ee_q_cal[AR5K_EEPROM_N_MODES];
u16 ee_fixed_bias[AR5K_EEPROM_N_MODES];
u16 ee_turbo_max_power[AR5K_EEPROM_N_MODES];
u16 ee_xr_power[AR5K_EEPROM_N_MODES];
u16 ee_switch_settling[AR5K_EEPROM_N_MODES];
u16 ee_ant_tx_rx[AR5K_EEPROM_N_MODES];
u16 ee_ant_control[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_PCDAC];
u16 ee_ob[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_OBDB];
u16 ee_db[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_OBDB];
u16 ee_tx_end2xlna_enable[AR5K_EEPROM_N_MODES];
u16 ee_tx_end2xpa_disable[AR5K_EEPROM_N_MODES];
u16 ee_tx_frm2xpa_enable[AR5K_EEPROM_N_MODES];
u16 ee_thr_62[AR5K_EEPROM_N_MODES];
u16 ee_xlna_gain[AR5K_EEPROM_N_MODES];
u16 ee_xpd[AR5K_EEPROM_N_MODES];
u16 ee_x_gain[AR5K_EEPROM_N_MODES];
u16 ee_i_gain[AR5K_EEPROM_N_MODES];
u16 ee_margin_tx_rx[AR5K_EEPROM_N_MODES];
/* Unused */
u16 ee_false_detect[AR5K_EEPROM_N_MODES];
u16 ee_cal_pier[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_2GHZ_CHAN];
u16 ee_channel[AR5K_EEPROM_N_MODES][AR5K_EEPROM_MAX_CHAN]; /*empty*/
/* Conformance test limits (Unused) */
u16 ee_ctls;
u16 ee_ctl[AR5K_EEPROM_MAX_CTLS];
/* Noise Floor Calibration settings */
s16 ee_noise_floor_thr[AR5K_EEPROM_N_MODES];
s8 ee_adc_desired_size[AR5K_EEPROM_N_MODES];
s8 ee_pga_desired_size[AR5K_EEPROM_N_MODES];
};
/*
* Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
* Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
/****************\
GPIO Functions
\****************/
#include "ath5k.h"
#include "reg.h"
#include "debug.h"
#include "base.h"
/*
* Set led state
*/
void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state)
{
u32 led;
/*5210 has different led mode handling*/
u32 led_5210;
ATH5K_TRACE(ah->ah_sc);
/*Reset led status*/
if (ah->ah_version != AR5K_AR5210)
AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG,
AR5K_PCICFG_LEDMODE | AR5K_PCICFG_LED);
else
AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_LED);
/*
* Some blinking values, define at your wish
*/
switch (state) {
case AR5K_LED_SCAN:
case AR5K_LED_AUTH:
led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_PEND;
led_5210 = AR5K_PCICFG_LED_PEND | AR5K_PCICFG_LED_BCTL;
break;
case AR5K_LED_INIT:
led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_NONE;
led_5210 = AR5K_PCICFG_LED_PEND;
break;
case AR5K_LED_ASSOC:
case AR5K_LED_RUN:
led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_ASSOC;
led_5210 = AR5K_PCICFG_LED_ASSOC;
break;
default:
led = AR5K_PCICFG_LEDMODE_PROM | AR5K_PCICFG_LED_NONE;
led_5210 = AR5K_PCICFG_LED_PEND;
break;
}
/*Write new status to the register*/
if (ah->ah_version != AR5K_AR5210)
AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, led);
else
AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, led_5210);
}
/*
* Set GPIO inputs
*/
int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio)
{
ATH5K_TRACE(ah->ah_sc);
if (gpio > AR5K_NUM_GPIO)
return -EINVAL;
ath5k_hw_reg_write(ah,
(ath5k_hw_reg_read(ah, AR5K_GPIOCR) & ~AR5K_GPIOCR_OUT(gpio))
| AR5K_GPIOCR_IN(gpio), AR5K_GPIOCR);
return 0;
}
/*
* Set GPIO outputs
*/
int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio)
{
ATH5K_TRACE(ah->ah_sc);
if (gpio > AR5K_NUM_GPIO)
return -EINVAL;
ath5k_hw_reg_write(ah,
(ath5k_hw_reg_read(ah, AR5K_GPIOCR) & ~AR5K_GPIOCR_OUT(gpio))
| AR5K_GPIOCR_OUT(gpio), AR5K_GPIOCR);
return 0;
}
/*
* Get GPIO state
*/
u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio)
{
ATH5K_TRACE(ah->ah_sc);
if (gpio > AR5K_NUM_GPIO)
return 0xffffffff;
/* GPIO input magic */
return ((ath5k_hw_reg_read(ah, AR5K_GPIODI) & AR5K_GPIODI_M) >> gpio) &
0x1;
}
/*
* Set GPIO state
*/
int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val)
{
u32 data;
ATH5K_TRACE(ah->ah_sc);
if (gpio > AR5K_NUM_GPIO)
return -EINVAL;
/* GPIO output magic */
data = ath5k_hw_reg_read(ah, AR5K_GPIODO);
data &= ~(1 << gpio);
data |= (val & 1) << gpio;
ath5k_hw_reg_write(ah, data, AR5K_GPIODO);
return 0;
}
/*
* Initialize the GPIO interrupt (RFKill switch)
*/
void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio,
u32 interrupt_level)
{
u32 data;
ATH5K_TRACE(ah->ah_sc);
if (gpio > AR5K_NUM_GPIO)
return;
/*
* Set the GPIO interrupt
*/
data = (ath5k_hw_reg_read(ah, AR5K_GPIOCR) &
~(AR5K_GPIOCR_INT_SEL(gpio) | AR5K_GPIOCR_INT_SELH |
AR5K_GPIOCR_INT_ENA | AR5K_GPIOCR_OUT(gpio))) |
(AR5K_GPIOCR_INT_SEL(gpio) | AR5K_GPIOCR_INT_ENA);
ath5k_hw_reg_write(ah, interrupt_level ? data :
(data | AR5K_GPIOCR_INT_SELH), AR5K_GPIOCR);
ah->ah_imr |= AR5K_IMR_GPIO;
/* Enable GPIO interrupts */
AR5K_REG_ENABLE_BITS(ah, AR5K_PIMR, AR5K_IMR_GPIO);
}
This diff is collapsed.
/* /*
* Initial register settings functions * Initial register settings functions
* *
* Copyright (c) 2004, 2005, 2006, 2007 Reyk Floeter <reyk@openbsd.org> * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org>
* Copyright (c) 2006, 2007 Nick Kossifidis <mickflemm@gmail.com> * Copyright (c) 2006-2007 Nick Kossifidis <mickflemm@gmail.com>
* Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com> * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
...@@ -20,13 +20,9 @@ ...@@ -20,13 +20,9 @@
*/ */
#include "ath5k.h" #include "ath5k.h"
#include "base.h"
#include "reg.h" #include "reg.h"
#include "debug.h"
/* #include "base.h"
* MAC/PHY REGISTERS
*/
/* /*
* Mode-independent initial register writes * Mode-independent initial register writes
...@@ -65,10 +61,10 @@ static const struct ath5k_ini ar5210_ini[] = { ...@@ -65,10 +61,10 @@ static const struct ath5k_ini ar5210_ini[] = {
{ AR5K_TXCFG, AR5K_DMASIZE_128B }, { AR5K_TXCFG, AR5K_DMASIZE_128B },
{ AR5K_RXCFG, AR5K_DMASIZE_128B }, { AR5K_RXCFG, AR5K_DMASIZE_128B },
{ AR5K_CFG, AR5K_INIT_CFG }, { AR5K_CFG, AR5K_INIT_CFG },
{ AR5K_TOPS, AR5K_INIT_TOPS }, { AR5K_TOPS, 8 },
{ AR5K_RXNOFRM, AR5K_INIT_RXNOFRM }, { AR5K_RXNOFRM, 8 },
{ AR5K_RPGTO, AR5K_INIT_RPGTO }, { AR5K_RPGTO, 0 },
{ AR5K_TXNOFRM, AR5K_INIT_TXNOFRM }, { AR5K_TXNOFRM, 0 },
{ AR5K_SFR, 0 }, { AR5K_SFR, 0 },
{ AR5K_MIBC, 0 }, { AR5K_MIBC, 0 },
{ AR5K_MISC, 0 }, { AR5K_MISC, 0 },
......
This diff is collapsed.
/* /*
* PHY functions * PHY functions
* *
* Copyright (c) 2004, 2005, 2006, 2007 Reyk Floeter <reyk@openbsd.org> * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org>
* Copyright (c) 2006, 2007 Nick Kossifidis <mickflemm@gmail.com> * Copyright (c) 2006-2007 Nick Kossifidis <mickflemm@gmail.com>
* Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com> * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
...@@ -19,6 +19,8 @@ ...@@ -19,6 +19,8 @@
* *
*/ */
#define _ATH5K_PHY
#include <linux/delay.h> #include <linux/delay.h>
#include "ath5k.h" #include "ath5k.h"
...@@ -2501,3 +2503,5 @@ int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, unsigned int power) ...@@ -2501,3 +2503,5 @@ int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, unsigned int power)
return ath5k_hw_txpower(ah, channel, power); return ath5k_hw_txpower(ah, channel, power);
} }
#undef _ATH5K_PHY
This diff is collapsed.
/* /*
* Copyright (c) 2007 Nick Kossifidis <mickflemm@gmail.com> * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
* Copyright (c) 2004, 2005, 2006, 2007 Reyk Floeter <reyk@openbsd.org> * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
* Copyright (c) 2007 Michael Taylor <mike.taylor@apprion.com> * Copyright (c) 2007-2008 Michael Taylor <mike.taylor@apprion.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
...@@ -976,98 +976,6 @@ ...@@ -976,98 +976,6 @@
*/ */
#define AR5K_EEPROM_BASE 0x6000 #define AR5K_EEPROM_BASE 0x6000
/*
* Common ar5xxx EEPROM data offsets (set these on AR5K_EEPROM_BASE)
*/
#define AR5K_EEPROM_MAGIC 0x003d /* EEPROM Magic number */
#define AR5K_EEPROM_MAGIC_VALUE 0x5aa5 /* Default - found on EEPROM */
#define AR5K_EEPROM_MAGIC_5212 0x0000145c /* 5212 */
#define AR5K_EEPROM_MAGIC_5211 0x0000145b /* 5211 */
#define AR5K_EEPROM_MAGIC_5210 0x0000145a /* 5210 */
#define AR5K_EEPROM_PROTECT 0x003f /* EEPROM protect status */
#define AR5K_EEPROM_PROTECT_RD_0_31 0x0001 /* Read protection bit for offsets 0x0 - 0x1f */
#define AR5K_EEPROM_PROTECT_WR_0_31 0x0002 /* Write protection bit for offsets 0x0 - 0x1f */
#define AR5K_EEPROM_PROTECT_RD_32_63 0x0004 /* 0x20 - 0x3f */
#define AR5K_EEPROM_PROTECT_WR_32_63 0x0008
#define AR5K_EEPROM_PROTECT_RD_64_127 0x0010 /* 0x40 - 0x7f */
#define AR5K_EEPROM_PROTECT_WR_64_127 0x0020
#define AR5K_EEPROM_PROTECT_RD_128_191 0x0040 /* 0x80 - 0xbf (regdom) */
#define AR5K_EEPROM_PROTECT_WR_128_191 0x0080
#define AR5K_EEPROM_PROTECT_RD_192_207 0x0100 /* 0xc0 - 0xcf */
#define AR5K_EEPROM_PROTECT_WR_192_207 0x0200
#define AR5K_EEPROM_PROTECT_RD_208_223 0x0400 /* 0xd0 - 0xdf */
#define AR5K_EEPROM_PROTECT_WR_208_223 0x0800
#define AR5K_EEPROM_PROTECT_RD_224_239 0x1000 /* 0xe0 - 0xef */
#define AR5K_EEPROM_PROTECT_WR_224_239 0x2000
#define AR5K_EEPROM_PROTECT_RD_240_255 0x4000 /* 0xf0 - 0xff */
#define AR5K_EEPROM_PROTECT_WR_240_255 0x8000
#define AR5K_EEPROM_REG_DOMAIN 0x00bf /* EEPROM regdom */
#define AR5K_EEPROM_INFO_BASE 0x00c0 /* EEPROM header */
#define AR5K_EEPROM_INFO_MAX (0x400 - AR5K_EEPROM_INFO_BASE)
#define AR5K_EEPROM_INFO_CKSUM 0xffff
#define AR5K_EEPROM_INFO(_n) (AR5K_EEPROM_INFO_BASE + (_n))
#define AR5K_EEPROM_VERSION AR5K_EEPROM_INFO(1) /* EEPROM Version */
#define AR5K_EEPROM_VERSION_3_0 0x3000 /* No idea what's going on before this version */
#define AR5K_EEPROM_VERSION_3_1 0x3001 /* ob/db values for 2Ghz (ar5211_rfregs) */
#define AR5K_EEPROM_VERSION_3_2 0x3002 /* different frequency representation (eeprom_bin2freq) */
#define AR5K_EEPROM_VERSION_3_3 0x3003 /* offsets changed, has 32 CTLs (see below) and ee_false_detect (eeprom_read_modes) */
#define AR5K_EEPROM_VERSION_3_4 0x3004 /* has ee_i_gain ee_cck_ofdm_power_delta (eeprom_read_modes) */
#define AR5K_EEPROM_VERSION_4_0 0x4000 /* has ee_misc*, ee_cal_pier, ee_turbo_max_power and ee_xr_power (eeprom_init) */
#define AR5K_EEPROM_VERSION_4_1 0x4001 /* has ee_margin_tx_rx (eeprom_init) */
#define AR5K_EEPROM_VERSION_4_2 0x4002 /* has ee_cck_ofdm_gain_delta (eeprom_init) */
#define AR5K_EEPROM_VERSION_4_3 0x4003
#define AR5K_EEPROM_VERSION_4_4 0x4004
#define AR5K_EEPROM_VERSION_4_5 0x4005
#define AR5K_EEPROM_VERSION_4_6 0x4006 /* has ee_scaled_cck_delta */
#define AR5K_EEPROM_VERSION_4_7 0x4007
#define AR5K_EEPROM_MODE_11A 0
#define AR5K_EEPROM_MODE_11B 1
#define AR5K_EEPROM_MODE_11G 2
#define AR5K_EEPROM_HDR AR5K_EEPROM_INFO(2) /* Header that contains the device caps */
#define AR5K_EEPROM_HDR_11A(_v) (((_v) >> AR5K_EEPROM_MODE_11A) & 0x1)
#define AR5K_EEPROM_HDR_11B(_v) (((_v) >> AR5K_EEPROM_MODE_11B) & 0x1)
#define AR5K_EEPROM_HDR_11G(_v) (((_v) >> AR5K_EEPROM_MODE_11G) & 0x1)
#define AR5K_EEPROM_HDR_T_2GHZ_DIS(_v) (((_v) >> 3) & 0x1) /* Disable turbo for 2Ghz (?) */
#define AR5K_EEPROM_HDR_T_5GHZ_DBM(_v) (((_v) >> 4) & 0x7f) /* Max turbo power for a/XR mode (eeprom_init) */
#define AR5K_EEPROM_HDR_DEVICE(_v) (((_v) >> 11) & 0x7)
#define AR5K_EEPROM_HDR_T_5GHZ_DIS(_v) (((_v) >> 15) & 0x1) /* Disable turbo for 5Ghz (?) */
#define AR5K_EEPROM_HDR_RFKILL(_v) (((_v) >> 14) & 0x1) /* Device has RFKill support */
#define AR5K_EEPROM_RFKILL_GPIO_SEL 0x0000001c
#define AR5K_EEPROM_RFKILL_GPIO_SEL_S 2
#define AR5K_EEPROM_RFKILL_POLARITY 0x00000002
#define AR5K_EEPROM_RFKILL_POLARITY_S 1
/* Newer EEPROMs are using a different offset */
#define AR5K_EEPROM_OFF(_v, _v3_0, _v3_3) \
(((_v) >= AR5K_EEPROM_VERSION_3_3) ? _v3_3 : _v3_0)
#define AR5K_EEPROM_ANT_GAIN(_v) AR5K_EEPROM_OFF(_v, 0x00c4, 0x00c3)
#define AR5K_EEPROM_ANT_GAIN_5GHZ(_v) ((int8_t)(((_v) >> 8) & 0xff))
#define AR5K_EEPROM_ANT_GAIN_2GHZ(_v) ((int8_t)((_v) & 0xff))
/* calibration settings */
#define AR5K_EEPROM_MODES_11A(_v) AR5K_EEPROM_OFF(_v, 0x00c5, 0x00d4)
#define AR5K_EEPROM_MODES_11B(_v) AR5K_EEPROM_OFF(_v, 0x00d0, 0x00f2)
#define AR5K_EEPROM_MODES_11G(_v) AR5K_EEPROM_OFF(_v, 0x00da, 0x010d)
#define AR5K_EEPROM_CTL(_v) AR5K_EEPROM_OFF(_v, 0x00e4, 0x0128) /* Conformance test limits */
/* [3.1 - 3.3] */
#define AR5K_EEPROM_OBDB0_2GHZ 0x00ec
#define AR5K_EEPROM_OBDB1_2GHZ 0x00ed
/* Misc values available since EEPROM 4.0 */
#define AR5K_EEPROM_MISC0 0x00c4
#define AR5K_EEPROM_EARSTART(_v) ((_v) & 0xfff)
#define AR5K_EEPROM_EEMAP(_v) (((_v) >> 14) & 0x3)
#define AR5K_EEPROM_MISC1 0x00c5
#define AR5K_EEPROM_TARGET_PWRSTART(_v) ((_v) & 0xfff)
#define AR5K_EEPROM_HAS32KHZCRYSTAL(_v) (((_v) >> 14) & 0x1)
/* /*
* EEPROM data register * EEPROM data register
*/ */
...@@ -1950,13 +1858,13 @@ ...@@ -1950,13 +1858,13 @@
#define AR5K_PHY_GAIN_OFFSET_RXTX_FLAG 0x00020000 /* RX-TX flag (?) */ #define AR5K_PHY_GAIN_OFFSET_RXTX_FLAG 0x00020000 /* RX-TX flag (?) */
/* /*
* Desired size register * Desired ADC/PGA size register
* (for more infos read ANI patent) * (for more infos read ANI patent)
*/ */
#define AR5K_PHY_DESIRED_SIZE 0x9850 /* Register Address */ #define AR5K_PHY_DESIRED_SIZE 0x9850 /* Register Address */
#define AR5K_PHY_DESIRED_SIZE_ADC 0x000000ff /* Mask for ADC desired size */ #define AR5K_PHY_DESIRED_SIZE_ADC 0x000000ff /* Mask for ADC desired size */
#define AR5K_PHY_DESIRED_SIZE_PGA 0x0000ff00 /* Mask for PGA desired size */ #define AR5K_PHY_DESIRED_SIZE_PGA 0x0000ff00 /* Mask for PGA desired size */
#define AR5K_PHY_DESIRED_SIZE_TOT 0x0ff00000 /* Mask for Total desired size (?) */ #define AR5K_PHY_DESIRED_SIZE_TOT 0x0ff00000 /* Mask for Total desired size */
/* /*
* PHY signal register * PHY signal register
......
This diff is collapsed.
config ATH9K config ATH9K
tristate "Atheros 802.11n wireless cards support" tristate "Atheros 802.11n wireless cards support"
depends on PCI && MAC80211 && WLAN_80211 depends on PCI && MAC80211 && WLAN_80211
select MAC80211_LEDS
select LEDS_CLASS
select NEW_LEDS
---help--- ---help---
This module adds support for wireless adapters based on This module adds support for wireless adapters based on
Atheros IEEE 802.11n AR5008 and AR9001 family of chipsets. Atheros IEEE 802.11n AR5008 and AR9001 family of chipsets.
......
...@@ -1482,6 +1482,11 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1482,6 +1482,11 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_NOISE_DBM; IEEE80211_HW_NOISE_DBM;
hw->wiphy->interface_modes =
BIT(NL80211_IFTYPE_AP) |
BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_ADHOC);
SET_IEEE80211_DEV(hw, &pdev->dev); SET_IEEE80211_DEV(hw, &pdev->dev);
pci_set_drvdata(pdev, hw); pci_set_drvdata(pdev, hw);
......
...@@ -80,6 +80,18 @@ config B43_NPHY ...@@ -80,6 +80,18 @@ config B43_NPHY
SAY N. SAY N.
config B43_PHY_LP
bool "IEEE 802.11g LP-PHY support (BROKEN)"
depends on B43 && EXPERIMENTAL && BROKEN
---help---
Support for the LP-PHY.
The LP-PHY is an IEEE 802.11g based PHY built into some notebooks
and embedded devices.
THIS IS BROKEN AND DOES NOT WORK YET.
SAY N.
# This config option automatically enables b43 LEDS support, # This config option automatically enables b43 LEDS support,
# if it's possible. # if it's possible.
config B43_LEDS config B43_LEDS
......
...@@ -4,7 +4,8 @@ b43-$(CONFIG_B43_NPHY) += tables_nphy.o ...@@ -4,7 +4,8 @@ b43-$(CONFIG_B43_NPHY) += tables_nphy.o
b43-y += phy_common.o b43-y += phy_common.o
b43-y += phy_g.o b43-y += phy_g.o
b43-y += phy_a.o b43-y += phy_a.o
b43-$(CONFIG_B43_NPHY) += nphy.o b43-$(CONFIG_B43_NPHY) += phy_n.o
b43-$(CONFIG_B43_PHY_LP) += phy_lp.o
b43-y += sysfs.o b43-y += sysfs.o
b43-y += xmit.o b43-y += xmit.o
b43-y += lo.o b43-y += lo.o
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -103,7 +103,13 @@ void b43_ofdmtab_write32(struct b43_wldev *dev, u16 table, ...@@ -103,7 +103,13 @@ void b43_ofdmtab_write32(struct b43_wldev *dev, u16 table,
struct b43_phy_a { struct b43_phy_a {
bool initialised; /* Pointer to the table used to convert a
* TSSI value to dBm-Q5.2 */
const s8 *tssi2dbm;
/* Target idle TSSI */
int tgt_idle_tssi;
/* Current idle TSSI */
int cur_idle_tssi;//FIXME value currently not set
/* A-PHY TX Power control value. */ /* A-PHY TX Power control value. */
u16 txpwr_offset; u16 txpwr_offset;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -920,8 +920,6 @@ ...@@ -920,8 +920,6 @@
struct b43_wldev; struct b43_wldev;
struct b43_phy_n { struct b43_phy_n {
bool initialised;
//TODO lots of missing stuff //TODO lots of missing stuff
}; };
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment