Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 122014
b: refs/heads/master
c: 4ddbb7d
h: refs/heads/master
v: v3
  • Loading branch information
Tomas Winkler authored and John W. Linville committed Nov 21, 2008
1 parent 93fa9f8 commit 34045b0
Show file tree
Hide file tree
Showing 11 changed files with 130 additions and 245 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 8d86422a83d79e3d3241cf0f269fca0c2640bcee
refs/heads/master: 4ddbb7d060061e584cb2137f4c7e41e502a560b4
90 changes: 2 additions & 88 deletions trunk/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -819,64 +819,6 @@ enum {
#define IWL49_NUM_QUEUES 16
#define IWL49_NUM_AMPDU_QUEUES 8

#define IWL_TX_DMA_MASK (DMA_BIT_MASK(36) & ~0x3)
#define IWL_NUM_OF_TBS 20

static inline u8 iwl_get_dma_hi_addr(dma_addr_t addr)
{
return (sizeof(addr) > sizeof(u32) ? (addr >> 16) >> 16 : 0) & 0xF;
}
/**
* struct iwl_tfd_tb transmit buffer descriptor within transmit frame descriptor
*
* This structure contains dma address and length of transmission address
*
* @lo: low [31:0] portion of the dma address of TX buffer
* every even is unaligned on 16 bit boundary
* @hi_n_len 0-3 [35:32] portion of dma
* 4-16 length of the tx buffer
*/
struct iwl_tfd_tb {
__le32 lo;
__le16 hi_n_len;
} __attribute__((packed));

/**
* struct iwl_tfd
*
* Transmit Frame Descriptor (TFD)
*
* @ __reserved1[3] reserved
* @ num_tbs 0-5 number of active tbs
* 6-7 padding (not used)
* @ tbs[20] transmit frame buffer descriptors
* @ __pad padding
*
* Each Tx queue uses a circular buffer of 256 TFDs stored in host DRAM.
* Both driver and device share these circular buffers, each of which must be
* contiguous 256 TFDs x 128 bytes-per-TFD = 32 KBytes
*
* Driver must indicate the physical address of the base of each
* circular buffer via the FH_MEM_CBBC_QUEUE registers.
*
* Each TFD contains pointer/size information for up to 20 data buffers
* in host DRAM. These buffers collectively contain the (one) frame described
* by the TFD. Each buffer must be a single contiguous block of memory within
* itself, but buffers may be scattered in host DRAM. Each buffer has max size
* of (4K - 4). The concatenates all of a TFD's buffers into a single
* Tx frame, up to 8 KBytes in size.
*
* A maximum of 255 (not 256!) TFDs may be on a queue waiting for Tx.
*
* Bit fields in the control dword (val0):
*/
struct iwl_tfd {
u8 __reserved1[3];
u8 num_tbs;
struct iwl_tfd_tb tbs[IWL_NUM_OF_TBS];
__le32 __pad;
} __attribute__ ((packed));


/**
* struct iwl4965_schedq_bc_tbl
Expand All @@ -896,37 +838,9 @@ struct iwl_tfd {
* padding puts each byte count table on a 1024-byte boundary;
* 4965 assumes tables are separated by 1024 bytes.
*/
struct iwl4965_schedq_bc_tbl {
struct iwl4965_scd_bc_tbl {
__le16 tfd_offset[TFD_QUEUE_BC_SIZE];
u8 pad[1024 - (TFD_QUEUE_BC_SIZE) * sizeof(__le16)];
} __attribute__ ((packed));


/**
* struct iwl4965_shared - handshake area for Tx and Rx
*
* For convenience in allocating memory, this structure combines 2 areas of
* DRAM which must be shared between driver and 4965. These do not need to
* be combined, if better allocation would result from keeping them separate:
*
* 1) The Tx byte count tables occupy 1024 bytes each (16 KBytes total for
* 16 queues). Driver uses SCD_DRAM_BASE_ADDR to tell 4965 where to find
* the first of these tables. 4965 assumes tables are 1024 bytes apart.
*
* 2) The Rx status (val0 and val1) occupies only 8 bytes. Driver uses
* FH_RSCSR_CHNL0_STTS_WPTR_REG to tell 4965 where to find this area.
* Driver reads val0 to determine the latest Receive Buffer Descriptor (RBD)
* that has been filled by the 4965.
*
* Bit fields val0:
* 31-12: Not used
* 11- 0: Index of last filled Rx buffer descriptor (4965 writes, driver reads)
*
* Bit fields val1:
* 31- 0: Not used
*/
struct iwl4965_shared {
struct iwl4965_schedq_bc_tbl queues_bc_tbls[IWL49_NUM_QUEUES];
} __attribute__ ((packed));

#endif /* __iwl4965_4965_hw_h__ */
#endif /* !__iwl_4965_hw_h__ */
35 changes: 6 additions & 29 deletions trunk/drivers/net/wireless/iwlwifi/iwl-4965.c
Original file line number Diff line number Diff line change
Expand Up @@ -715,8 +715,7 @@ static int iwl4965_alive_notify(struct iwl_priv *priv)

/* Tel 4965 where to find Tx byte count tables */
iwl_write_prph(priv, IWL49_SCD_DRAM_BASE_ADDR,
(priv->shared_phys +
offsetof(struct iwl4965_shared, queues_bc_tbls)) >> 10);
priv->scd_bc_tbls.dma >> 10);

/* Disable chain mode for all queues */
iwl_write_prph(priv, IWL49_SCD_QUEUECHAIN_SEL, 0);
Expand Down Expand Up @@ -804,6 +803,8 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
}

priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues;
priv->hw_params.scd_bc_tbls_size =
IWL49_NUM_QUEUES * sizeof(struct iwl4965_scd_bc_tbl);
priv->hw_params.max_stations = IWL4965_STATION_COUNT;
priv->hw_params.bcast_sta_id = IWL4965_BROADCAST_ID;
priv->hw_params.max_data_size = IWL49_RTC_DATA_SIZE;
Expand Down Expand Up @@ -1631,36 +1632,14 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel)
}
#endif

static int iwl4965_alloc_shared_mem(struct iwl_priv *priv)
{
priv->shared_virt = pci_alloc_consistent(priv->pci_dev,
sizeof(struct iwl4965_shared),
&priv->shared_phys);
if (!priv->shared_virt)
return -ENOMEM;

memset(priv->shared_virt, 0, sizeof(struct iwl4965_shared));

return 0;
}

static void iwl4965_free_shared_mem(struct iwl_priv *priv)
{
if (priv->shared_virt)
pci_free_consistent(priv->pci_dev,
sizeof(struct iwl4965_shared),
priv->shared_virt,
priv->shared_phys);
}

/**
* iwl4965_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array
*/
static void iwl4965_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
struct iwl_tx_queue *txq,
u16 byte_cnt)
{
struct iwl4965_shared *shared_data = priv->shared_virt;
struct iwl4965_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr;
int txq_id = txq->q.id;
int write_ptr = txq->q.write_ptr;
int len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE;
Expand All @@ -1670,11 +1649,11 @@ static void iwl4965_txq_update_byte_cnt_tbl(struct iwl_priv *priv,

bc_ent = cpu_to_le16(len & 0xFFF);
/* Set up byte count within first 256 entries */
shared_data->queues_bc_tbls[txq_id].tfd_offset[write_ptr] = bc_ent;
scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent;

/* If within first 64 entries, duplicate at end */
if (write_ptr < TFD_QUEUE_SIZE_BC_DUP)
shared_data->queues_bc_tbls[txq_id].
scd_bc_tbl[txq_id].
tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent;
}

Expand Down Expand Up @@ -2296,8 +2275,6 @@ static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {

static struct iwl_lib_ops iwl4965_lib = {
.set_hw_params = iwl4965_hw_set_hw_params,
.alloc_shared_mem = iwl4965_alloc_shared_mem,
.free_shared_mem = iwl4965_free_shared_mem,
.txq_update_byte_cnt_tbl = iwl4965_txq_update_byte_cnt_tbl,
.txq_set_sched = iwl4965_txq_set_sched,
.txq_agg_enable = iwl4965_txq_agg_enable,
Expand Down
8 changes: 1 addition & 7 deletions trunk/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,16 +90,10 @@
* @tfd_offset 0-12 - tx command byte count
* 12-16 - station index
*/
struct iwl5000_schedq_bc_tbl {
struct iwl5000_scd_bc_tbl {
__le16 tfd_offset[TFD_QUEUE_BC_SIZE];
} __attribute__ ((packed));

/**
* struct iwl5000_shared
*/
struct iwl5000_shared {
struct iwl5000_schedq_bc_tbl queues_bc_tbls[IWL50_NUM_QUEUES];
} __attribute__ ((packed));

#endif /* __iwl_5000_hw_h__ */

45 changes: 10 additions & 35 deletions trunk/drivers/net/wireless/iwlwifi/iwl-5000.c
Original file line number Diff line number Diff line change
Expand Up @@ -721,11 +721,9 @@ static int iwl5000_alive_notify(struct iwl_priv *priv)
iwl_write_targ_mem(priv, a, 0);

iwl_write_prph(priv, IWL50_SCD_DRAM_BASE_ADDR,
(priv->shared_phys +
offsetof(struct iwl5000_shared, queues_bc_tbls)) >> 10);
priv->scd_bc_tbls.dma >> 10);
iwl_write_prph(priv, IWL50_SCD_QUEUECHAIN_SEL,
IWL50_SCD_QUEUECHAIN_SEL_ALL(
priv->hw_params.max_txq_num));
IWL50_SCD_QUEUECHAIN_SEL_ALL(priv->hw_params.max_txq_num));
iwl_write_prph(priv, IWL50_SCD_AGGR_SEL, 0);

/* initiate the queues */
Expand Down Expand Up @@ -788,6 +786,8 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
}

priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues;
priv->hw_params.scd_bc_tbls_size =
IWL50_NUM_QUEUES * sizeof(struct iwl5000_scd_bc_tbl);
priv->hw_params.max_stations = IWL5000_STATION_COUNT;
priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
priv->hw_params.max_data_size = IWL50_RTC_DATA_SIZE;
Expand Down Expand Up @@ -853,36 +853,14 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
return 0;
}

static int iwl5000_alloc_shared_mem(struct iwl_priv *priv)
{
priv->shared_virt = pci_alloc_consistent(priv->pci_dev,
sizeof(struct iwl5000_shared),
&priv->shared_phys);
if (!priv->shared_virt)
return -ENOMEM;

memset(priv->shared_virt, 0, sizeof(struct iwl5000_shared));

return 0;
}

static void iwl5000_free_shared_mem(struct iwl_priv *priv)
{
if (priv->shared_virt)
pci_free_consistent(priv->pci_dev,
sizeof(struct iwl5000_shared),
priv->shared_virt,
priv->shared_phys);
}

/**
* iwl5000_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array
*/
static void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
struct iwl_tx_queue *txq,
u16 byte_cnt)
{
struct iwl5000_shared *shared_data = priv->shared_virt;
struct iwl5000_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr;
int write_ptr = txq->q.write_ptr;
int txq_id = txq->q.id;
u8 sec_ctl = 0;
Expand Down Expand Up @@ -911,17 +889,17 @@ static void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv,

bc_ent = cpu_to_le16((len & 0xFFF) | (sta_id << 12));

shared_data->queues_bc_tbls[txq_id].tfd_offset[write_ptr] = bc_ent;
scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent;

if (txq->q.write_ptr < TFD_QUEUE_SIZE_BC_DUP)
shared_data->queues_bc_tbls[txq_id].
scd_bc_tbl[txq_id].
tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent;
}

static void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
struct iwl_tx_queue *txq)
{
struct iwl5000_shared *shared_data = priv->shared_virt;
struct iwl5000_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr;
int txq_id = txq->q.id;
int read_ptr = txq->q.read_ptr;
u8 sta_id = 0;
Expand All @@ -933,11 +911,10 @@ static void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
sta_id = txq->cmd[read_ptr]->cmd.tx.sta_id;

bc_ent = cpu_to_le16(1 | (sta_id << 12));
shared_data->queues_bc_tbls[txq_id].
tfd_offset[read_ptr] = bc_ent;
scd_bc_tbl[txq_id].tfd_offset[read_ptr] = bc_ent;

if (txq->q.write_ptr < TFD_QUEUE_SIZE_BC_DUP)
shared_data->queues_bc_tbls[txq_id].
scd_bc_tbl[txq_id].
tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] = bc_ent;
}

Expand Down Expand Up @@ -1450,8 +1427,6 @@ static struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = {

static struct iwl_lib_ops iwl5000_lib = {
.set_hw_params = iwl5000_hw_set_hw_params,
.alloc_shared_mem = iwl5000_alloc_shared_mem,
.free_shared_mem = iwl5000_free_shared_mem,
.txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl,
.txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl,
.txq_set_sched = iwl5000_txq_set_sched,
Expand Down
8 changes: 0 additions & 8 deletions trunk/drivers/net/wireless/iwlwifi/iwl-agn.c
Original file line number Diff line number Diff line change
Expand Up @@ -2196,8 +2196,6 @@ static void __iwl_down(struct iwl_priv *priv)
priv->cfg->ops->lib->apm_ops.stop(priv);
else
priv->cfg->ops->lib->apm_ops.reset(priv);
priv->cfg->ops->lib->free_shared_mem(priv);

exit:
memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp));

Expand Down Expand Up @@ -2250,12 +2248,6 @@ static int __iwl_up(struct iwl_priv *priv)

iwl_write32(priv, CSR_INT, 0xFFFFFFFF);

ret = priv->cfg->ops->lib->alloc_shared_mem(priv);
if (ret) {
IWL_ERROR("Unable to allocate shared memory\n");
return ret;
}

ret = iwl_hw_nic_init(priv);
if (ret) {
IWL_ERROR("Unable to init nic\n");
Expand Down
46 changes: 0 additions & 46 deletions trunk/drivers/net/wireless/iwlwifi/iwl-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,52 +189,6 @@ void iwl_hw_detect(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_hw_detect);

/* Tell nic where to find the "keep warm" buffer */
int iwl_kw_init(struct iwl_priv *priv)
{
unsigned long flags;
int ret;

spin_lock_irqsave(&priv->lock, flags);
ret = iwl_grab_nic_access(priv);
if (ret)
goto out;

iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG,
priv->kw.dma_addr >> 4);
iwl_release_nic_access(priv);
out:
spin_unlock_irqrestore(&priv->lock, flags);
return ret;
}

int iwl_kw_alloc(struct iwl_priv *priv)
{
struct pci_dev *dev = priv->pci_dev;
struct iwl_kw *kw = &priv->kw;

kw->size = IWL_KW_SIZE;
kw->v_addr = pci_alloc_consistent(dev, kw->size, &kw->dma_addr);
if (!kw->v_addr)
return -ENOMEM;

return 0;
}

/**
* iwl_kw_free - Free the "keep warm" buffer
*/
void iwl_kw_free(struct iwl_priv *priv)
{
struct pci_dev *dev = priv->pci_dev;
struct iwl_kw *kw = &priv->kw;

if (kw->v_addr) {
pci_free_consistent(dev, kw->size, kw->v_addr, kw->dma_addr);
memset(kw, 0, sizeof(*kw));
}
}

int iwl_hw_nic_init(struct iwl_priv *priv)
{
unsigned long flags;
Expand Down
Loading

0 comments on commit 34045b0

Please sign in to comment.