Updated iprowifi4965 based on iwn FreeBSD 8.1.0 with the following changes:

* added more firmware to be used by the driver and updated the old one.
* avoid the switch to using ICT interrupt mode (dunno what it implies on Haiku)
* commented ieee80211_ratectl_*() calls. They can be uncommented when we support them.
* added ieee80211_ratectl.h with functions commented out
Switch to using ICT interrupt mode


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38734 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Jérôme Duval
2010-09-19 23:18:06 +00:00
parent b15383313c
commit cceb9427a8
6 changed files with 6388 additions and 3434 deletions
@@ -1,15 +1,15 @@
SubDir HAIKU_TOP src add-ons kernel drivers network wlan iprowifi4965 ;
UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd_network compat ]
UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd_network compat ]
: true ;
UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd_wlan ] : true ;
UsePrivateHeaders net system ;
UsePrivateKernelHeaders ;
SubDirCcFlags [ FDefines _KERNEL=1 FBSD_DRIVER=1 ]
-Wno-format
-Wno-unused
-Wno-uninitialized
SubDirCcFlags [ FDefines _KERNEL=1 FBSD_DRIVER=1 ]
-Wno-format
-Wno-unused
-Wno-uninitialized
-Werror ;
UseHeaders [ FDirName $(SUBDIR) ] : true ;
@@ -24,12 +24,12 @@ KernelAddon iprowifi4965 :
libfreebsd_network.a
;
HAIKU_WIFI_FIRMWARE_PACKAGES on iprowifi4965 =
iwlwifi-1000-ucode-128.50.3.1 iwlwifi-4965-ucode-4.44.1.20
HAIKU_WIFI_FIRMWARE_PACKAGES on iprowifi4965 =
iwlwifi-1000-ucode-128.50.3.1 iwlwifi-4965-ucode-228.61.2.24
iwlwifi-5000-ucode-8.24.2.12 iwlwifi-5150-ucode-8.24.2.2
iwlwifi-6000-ucode-9.221.4.1 iwlwifi-6050-ucode-9.201.4.1 ;
HAIKU_WIFI_FIRMWARE_ARCHIVES on iprowifi4965 =
iwlwifi-1000-ucode-128.50.3.1.tgz iwlwifi-4965-ucode-4.44.1.20.tgz
HAIKU_WIFI_FIRMWARE_ARCHIVES on iprowifi4965 =
iwlwifi-1000-ucode-128.50.3.1.tgz iwlwifi-4965-ucode-228.61.2.24.tgz
iwlwifi-5000-ucode-8.24.2.12.tgz iwlwifi-5150-ucode-8.24.2.2.tgz
iwlwifi-6000-ucode-9.221.4.1.tgz iwlwifi-6050-ucode-9.201.4.1.tgz ;
HAIKU_WIFI_FIRMWARE_DO_EXTRACT on iprowifi4965 = true ;
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,6 +1,8 @@
/* $FreeBSD$ */
/* $OpenBSD: if_iwnvar.h,v 1.17 2010/02/17 18:23:00 damien Exp $ */
/*-
* Copyright (c) 2007
* Copyright (c) 2007, 2008
* Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 2008 Sam Leffler, Errno Consulting
*
@@ -60,6 +62,8 @@ struct iwn_dma_info {
struct iwn_tx_data {
bus_dmamap_t map;
bus_addr_t cmd_paddr;
bus_addr_t scratch_paddr;
struct mbuf *m;
struct ieee80211_node *ni;
};
@@ -76,14 +80,18 @@ struct iwn_tx_ring {
int cur;
};
struct iwn_softc;
struct iwn_rx_data {
bus_dmamap_t map;
struct mbuf *m;
struct mbuf *m;
bus_dmamap_t map;
};
struct iwn_rx_ring {
struct iwn_dma_info desc_dma;
struct iwn_dma_info stat_dma;
uint32_t *desc;
struct iwn_rx_status *stat;
struct iwn_rx_data data[IWN_RX_RING_COUNT];
bus_dma_tag_t data_dmat;
int cur;
@@ -91,24 +99,26 @@ struct iwn_rx_ring {
struct iwn_node {
struct ieee80211_node ni; /* must be the first */
struct ieee80211_amrr_node amn;
uint16_t disable_tid;
uint8_t id;
uint8_t ridx[IEEE80211_RATE_MAXSIZE];
};
#define IWN_NODE(_ni) ((struct iwn_node *)(_ni))
struct iwn_calib_state {
uint8_t state;
#define IWN_CALIB_STATE_INIT 0
#define IWN_CALIB_STATE_ASSOC 1
#define IWN_CALIB_STATE_RUN 2
u_int nbeacons;
uint32_t noise[3];
uint32_t rssi[3];
uint32_t corr_ofdm_x1;
uint32_t corr_ofdm_mrc_x1;
uint32_t corr_ofdm_x4;
uint32_t corr_ofdm_mrc_x4;
uint32_t corr_cck_x4;
uint32_t corr_cck_mrc_x4;
uint32_t ofdm_x1;
uint32_t ofdm_mrc_x1;
uint32_t ofdm_x4;
uint32_t ofdm_mrc_x4;
uint32_t cck_x4;
uint32_t cck_mrc_x4;
uint32_t bad_plcp_ofdm;
uint32_t fa_ofdm;
uint32_t bad_plcp_cck;
@@ -118,6 +128,7 @@ struct iwn_calib_state {
#define IWN_CCK_STATE_INIT 0
#define IWN_CCK_STATE_LOFA 1
#define IWN_CCK_STATE_HIFA 2
uint8_t noise_samples[20];
u_int cur_noise_sample;
uint8_t noise_ref;
@@ -126,10 +137,62 @@ struct iwn_calib_state {
uint32_t energy_cck;
};
struct iwn_calib_info {
uint8_t *buf;
u_int len;
};
struct iwn_fw_part {
const uint8_t *text;
uint32_t textsz;
const uint8_t *data;
uint32_t datasz;
};
struct iwn_fw_info {
u_char *data;
struct iwn_fw_part init;
struct iwn_fw_part main;
struct iwn_fw_part boot;
};
struct iwn_hal {
int (*load_firmware)(struct iwn_softc *);
void (*read_eeprom)(struct iwn_softc *);
int (*post_alive)(struct iwn_softc *);
int (*nic_config)(struct iwn_softc *);
void (*update_sched)(struct iwn_softc *, int, int, uint8_t,
uint16_t);
int (*get_temperature)(struct iwn_softc *);
int (*get_rssi)(struct iwn_softc *, struct iwn_rx_stat *);
int (*set_txpower)(struct iwn_softc *,
struct ieee80211_channel *, int);
int (*init_gains)(struct iwn_softc *);
int (*set_gains)(struct iwn_softc *);
int (*add_node)(struct iwn_softc *, struct iwn_node_info *,
int);
void (*tx_done)(struct iwn_softc *, struct iwn_rx_desc *,
struct iwn_rx_data *);
#if 0 /* HT */
void (*ampdu_tx_start)(struct iwn_softc *,
struct ieee80211_node *, uint8_t, uint16_t);
void (*ampdu_tx_stop)(struct iwn_softc *, uint8_t,
uint16_t);
#endif
int ntxqs;
int ndmachnls;
uint8_t broadcast_id;
int rxonsz;
int schedsz;
uint32_t fw_text_maxsz;
uint32_t fw_data_maxsz;
uint32_t fwsz;
bus_size_t sched_txfact_addr;
};
struct iwn_vap {
struct ieee80211vap iv_vap;
struct ieee80211_amrr iv_amrr;
struct callout iv_amrr_to;
uint8_t iv_ridx;
int (*iv_newstate)(struct ieee80211vap *,
enum ieee80211_state, int);
@@ -139,67 +202,107 @@ struct iwn_vap {
struct iwn_softc {
struct ifnet *sc_ifp;
int sc_debug;
struct callout sc_timer_to; /* calib+watchdog timer */
int sc_tx_timer; /* tx watchdog timer/counter */
const struct ieee80211_channel *sc_curchan;
struct iwn_rx_radiotap_header sc_rxtap;
struct iwn_tx_radiotap_header sc_txtap;
/* locks */
/* Locks */
struct mtx sc_mtx;
/* bus */
/* Bus */
device_t sc_dev;
int mem_rid;
int irq_rid;
struct resource *mem;
struct resource *irq;
/* shared area */
struct iwn_dma_info shared_dma;
struct iwn_shared *shared;
u_int sc_flags;
#define IWN_FLAG_HAS_5GHZ (1 << 0)
#define IWN_FLAG_HAS_OTPROM (1 << 1)
#define IWN_FLAG_CALIB_DONE (1 << 2)
#define IWN_FLAG_USE_ICT (1 << 3)
#define IWN_FLAG_INTERNAL_PA (1 << 4)
/* "keep warm" page */
uint8_t hw_type;
const struct iwn_hal *sc_hal;
const char *fwname;
const struct iwn_sensitivity_limits
*limits;
/* TX scheduler rings. */
struct iwn_dma_info sched_dma;
uint16_t *sched;
uint32_t sched_base;
/* "Keep Warm" page. */
struct iwn_dma_info kw_dma;
/* firmware image */
/* Firmware image. */
const struct firmware *fw_fp;
/* firmware DMA transfer */
/* Firmware DMA transfer. */
struct iwn_dma_info fw_dma;
/* rings */
struct iwn_tx_ring txq[IWN_NTXQUEUES];
/* ICT table. */
struct iwn_dma_info ict_dma;
uint32_t *ict;
int ict_cur;
/* TX/RX rings. */
struct iwn_tx_ring txq[IWN5000_NTXQUEUES];
struct iwn_rx_ring rxq;
bus_space_tag_t sc_st;
bus_space_handle_t sc_sh;
void *sc_ih;
bus_size_t sc_sz;
int sc_cap_off; /* PCIe Capabilities. */
/* Tasks used by the driver */
struct task sc_reinit_task;
struct task sc_radioon_task;
struct task sc_radiooff_task;
/* Thermal calibration */
int calib_cnt;
struct iwn_calib_state calib;
struct iwn_fw_info fw;
struct iwn_calib_info calibcmd[5];
uint32_t errptr;
struct iwn_rx_stat last_rx_stat;
int last_rx_valid;
struct iwn_ucode_info ucode_info;
struct iwn_config config;
struct iwn_rxon rxon;
uint32_t rawtemp;
int temp;
int noise;
uint8_t antmsk;
uint32_t qfullmsk;
struct iwn_eeprom_band bands[IWN_NBANDS];
uint32_t prom_base;
struct iwn4965_eeprom_band
bands[IWN_NBANDS];
struct iwn_eeprom_chan eeprom_channels[IWN_NBANDS][IWN_MAX_CHAN_PER_BAND];
uint16_t rfcfg;
uint8_t calib_ver;
char eeprom_domain[4];
uint32_t eeprom_crystal;
int16_t eeprom_voltage;
int8_t maxpwr2GHz;
int8_t maxpwr5GHz;
int8_t maxpwr[IEEE80211_CHAN_MAX];
int8_t enh_maxpwr[35];
int32_t temp_off;
uint32_t int_mask;
uint8_t ntxchains;
uint8_t nrxchains;
uint8_t txchainmask;
uint8_t rxchainmask;
uint8_t chainmask;
struct callout sc_timer_to;
int sc_tx_timer;
struct iwn_rx_radiotap_header sc_rxtap;
struct iwn_tx_radiotap_header sc_txtap;
#if defined(__HAIKU__)
uint32_t sc_intr_status_1;
@@ -24,7 +24,13 @@ NO_HAIKU_FBSD_MII_DRIVER();
NO_HAIKU_REENABLE_INTERRUPTS();
HAIKU_DRIVER_REQUIREMENTS(FBSD_TASKQUEUES | FBSD_WLAN);
HAIKU_FIRMWARE_VERSION(44417);
HAIKU_FIRMWARE_NAME_MAP(1) = {{"iwnfw", "iwlwifi-4965-1.ucode"}};
HAIKU_FIRMWARE_NAME_MAP(5) = {
{"iwn1000fw", "iwlwifi-1000-3.ucode"},
{"iwn4965fw", "iwlwifi-4965-2.ucode"},
{"iwn5000fw", "iwlwifi-5000-2.ucode"},
{"iwn5150fw", "iwlwifi-5150-2.ucode"},
{"iwn6000fw", "iwlwifi-6000-4.ucode"}
};
int
@@ -33,12 +39,12 @@ HAIKU_CHECK_DISABLE_INTERRUPTS(device_t dev)
struct iwn_softc* sc = (struct iwn_softc*)device_get_softc(dev);
uint32 r1, r2;
r1 = IWN_READ(sc, IWN_INTR);
r2 = IWN_READ(sc, IWN_INTR_STATUS);
r1 = IWN_READ(sc, IWN_INT);
r2 = IWN_READ(sc, IWN_FH_INT);
if (r1 == 0 && r2 == 0) {
// not for us
IWN_WRITE(sc, IWN_MASK, IWN_INTR_MASK);
IWN_WRITE(sc, IWN_INT_MASK, sc->int_mask);
return 0;
}
@@ -50,7 +56,7 @@ HAIKU_CHECK_DISABLE_INTERRUPTS(device_t dev)
atomic_set((int32*)&sc->sc_intr_status_1, r1);
atomic_set((int32*)&sc->sc_intr_status_2, r2);
IWN_WRITE(sc, IWN_MASK, 0);
IWN_WRITE(sc, IWN_INT_MASK, 0);
// disable interrupts
return 1;
@@ -0,0 +1,130 @@
/*-
* Copyright (c) 2010 Rui Paulo <rpaulo@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
enum ieee80211_ratealgs {
IEEE80211_RATECTL_AMRR = 0,
IEEE80211_RATECTL_RSSADAPT = 1,
IEEE80211_RATECTL_ONOE = 2,
IEEE80211_RATECTL_SAMPLE = 3,
IEEE80211_RATECTL_MAX
};
#define IEEE80211_RATECTL_TX_SUCCESS 1
#define IEEE80211_RATECTL_TX_FAILURE 0
struct ieee80211_ratectl {
const char *ir_name;
int (*ir_attach)(const struct ieee80211vap *);
void (*ir_detach)(const struct ieee80211vap *);
void (*ir_init)(struct ieee80211vap *);
void (*ir_deinit)(struct ieee80211vap *);
void (*ir_node_init)(struct ieee80211_node *);
void (*ir_node_deinit)(struct ieee80211_node *);
int (*ir_rate)(struct ieee80211_node *, void *, uint32_t);
void (*ir_tx_complete)(const struct ieee80211vap *,
const struct ieee80211_node *, int,
void *, void *);
void (*ir_tx_update)(const struct ieee80211vap *,
const struct ieee80211_node *,
void *, void *, void *);
void (*ir_setinterval)(const struct ieee80211vap *, int);
};
void ieee80211_ratectl_register(int, const struct ieee80211_ratectl *);
void ieee80211_ratectl_unregister(int);
void ieee80211_ratectl_set(struct ieee80211vap *, int);
MALLOC_DECLARE(M_80211_RATECTL);
#ifndef __HAIKU__
static void __inline
ieee80211_ratectl_init(struct ieee80211vap *vap)
{
vap->iv_rate->ir_init(vap);
}
static void __inline
ieee80211_ratectl_deinit(struct ieee80211vap *vap)
{
vap->iv_rate->ir_deinit(vap);
}
static void __inline
ieee80211_ratectl_node_init(struct ieee80211_node *ni)
{
const struct ieee80211vap *vap = ni->ni_vap;
vap->iv_rate->ir_node_init(ni);
}
static void __inline
ieee80211_ratectl_node_deinit(struct ieee80211_node *ni)
{
const struct ieee80211vap *vap = ni->ni_vap;
if (ni->ni_rctls == NULL) /* ratectl not setup */
return;
vap->iv_rate->ir_node_deinit(ni);
}
static int __inline
ieee80211_ratectl_rate(struct ieee80211_node *ni, void *arg, uint32_t iarg)
{
const struct ieee80211vap *vap = ni->ni_vap;
if (ni->ni_rctls == NULL) /* ratectl not setup */
return 0;
return vap->iv_rate->ir_rate(ni, arg, iarg);
}
static void __inline
ieee80211_ratectl_tx_complete(const struct ieee80211vap *vap,
const struct ieee80211_node *ni, int status, void *arg1, void *arg2)
{
if (ni->ni_rctls == NULL) /* ratectl not setup */
return;
vap->iv_rate->ir_tx_complete(vap, ni, status, arg1, arg2);
}
static void __inline
ieee80211_ratectl_tx_update(const struct ieee80211vap *vap,
const struct ieee80211_node *ni, void *arg1, void *arg2, void *arg3)
{
if (vap->iv_rate->ir_tx_update == NULL)
return;
if (ni->ni_rctls == NULL) /* ratectl not setup */
return;
vap->iv_rate->ir_tx_update(vap, ni, arg1, arg2, arg3);
}
static void __inline
ieee80211_ratectl_setinterval(const struct ieee80211vap *vap, int msecs)
{
if (vap->iv_rate->ir_setinterval == NULL)
return;
vap->iv_rate->ir_setinterval(vap, msecs);
}
#endif