Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
aa3c90b8
Commit
aa3c90b8
authored
Jan 22, 2013
by
John W. Linville
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'for-john' of
git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next
parents
660b9caa
1c3fea82
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
212 additions
and
68 deletions
+212
-68
drivers/net/wireless/iwlwifi/dvm/mac80211.c
drivers/net/wireless/iwlwifi/dvm/mac80211.c
+3
-5
drivers/net/wireless/iwlwifi/dvm/tx.c
drivers/net/wireless/iwlwifi/dvm/tx.c
+16
-12
drivers/net/wireless/iwlwifi/iwl-fh.h
drivers/net/wireless/iwlwifi/iwl-fh.h
+4
-0
drivers/net/wireless/iwlwifi/iwl-trans.h
drivers/net/wireless/iwlwifi/iwl-trans.h
+27
-5
drivers/net/wireless/iwlwifi/pcie/internal.h
drivers/net/wireless/iwlwifi/pcie/internal.h
+2
-0
drivers/net/wireless/iwlwifi/pcie/rx.c
drivers/net/wireless/iwlwifi/pcie/rx.c
+8
-4
drivers/net/wireless/iwlwifi/pcie/trans.c
drivers/net/wireless/iwlwifi/pcie/trans.c
+118
-22
drivers/net/wireless/iwlwifi/pcie/tx.c
drivers/net/wireless/iwlwifi/pcie/tx.c
+34
-20
No files found.
drivers/net/wireless/iwlwifi/dvm/mac80211.c
View file @
aa3c90b8
...
...
@@ -206,7 +206,8 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
#ifdef CONFIG_PM_SLEEP
if
(
priv
->
fw
->
img
[
IWL_UCODE_WOWLAN
].
sec
[
0
].
len
&&
priv
->
trans
->
ops
->
wowlan_suspend
&&
priv
->
trans
->
ops
->
d3_suspend
&&
priv
->
trans
->
ops
->
d3_resume
&&
device_can_wakeup
(
priv
->
trans
->
dev
))
{
hw
->
wiphy
->
wowlan
.
flags
=
WIPHY_WOWLAN_MAGIC_PKT
|
WIPHY_WOWLAN_DISCONNECT
|
...
...
@@ -426,7 +427,7 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw,
if
(
ret
)
goto
error
;
iwl_trans_
wowlan
_suspend
(
priv
->
trans
);
iwl_trans_
d3
_suspend
(
priv
->
trans
);
goto
out
;
...
...
@@ -520,9 +521,6 @@ static void iwlagn_mac_tx(struct ieee80211_hw *hw,
{
struct
iwl_priv
*
priv
=
IWL_MAC80211_GET_DVM
(
hw
);
IWL_DEBUG_TX
(
priv
,
"dev->xmit(%d bytes) at rate 0x%02x
\n
"
,
skb
->
len
,
ieee80211_get_tx_rate
(
hw
,
IEEE80211_SKB_CB
(
skb
))
->
bitrate
);
if
(
iwlagn_tx_skb
(
priv
,
control
->
sta
,
skb
))
ieee80211_free_txskb
(
hw
,
skb
);
}
...
...
drivers/net/wireless/iwlwifi/dvm/tx.c
View file @
aa3c90b8
...
...
@@ -231,13 +231,11 @@ static void iwlagn_tx_cmd_build_hwcrypto(struct iwl_priv *priv,
memcpy
(
tx_cmd
->
key
,
keyconf
->
key
,
keyconf
->
keylen
);
if
(
info
->
flags
&
IEEE80211_TX_CTL_AMPDU
)
tx_cmd
->
tx_flags
|=
TX_CMD_FLG_AGG_CCMP_MSK
;
IWL_DEBUG_TX
(
priv
,
"tx_cmd with AES hwcrypto
\n
"
);
break
;
case
WLAN_CIPHER_SUITE_TKIP
:
tx_cmd
->
sec_ctl
=
TX_CMD_SEC_TKIP
;
ieee80211_get_tkip_p2k
(
keyconf
,
skb_frag
,
tx_cmd
->
key
);
IWL_DEBUG_TX
(
priv
,
"tx_cmd with tkip hwcrypto
\n
"
);
break
;
case
WLAN_CIPHER_SUITE_WEP104
:
...
...
@@ -355,8 +353,6 @@ int iwlagn_tx_skb(struct iwl_priv *priv,
}
}
IWL_DEBUG_TX
(
priv
,
"station Id %d
\n
"
,
sta_id
);
if
(
sta
)
sta_priv
=
(
void
*
)
sta
->
drv_priv
;
...
...
@@ -472,6 +468,9 @@ int iwlagn_tx_skb(struct iwl_priv *priv,
WARN_ON_ONCE
(
is_agg
&&
priv
->
queue_to_mac80211
[
txq_id
]
!=
info
->
hw_queue
);
IWL_DEBUG_TX
(
priv
,
"TX to [%d|%d] Q:%d - seq: 0x%x
\n
"
,
sta_id
,
tid
,
txq_id
,
seq_number
);
if
(
iwl_trans_tx
(
priv
->
trans
,
skb
,
dev_cmd
,
txq_id
))
goto
drop_unlock_sta
;
...
...
@@ -953,12 +952,6 @@ static void iwl_rx_reply_tx_agg(struct iwl_priv *priv,
if
(
status
&
(
AGG_TX_STATE_FEW_BYTES_MSK
|
AGG_TX_STATE_ABORT_MSK
))
continue
;
IWL_DEBUG_TX_REPLY
(
priv
,
"status %s (0x%08x), "
"try-count (0x%08x)
\n
"
,
iwl_get_agg_tx_fail_reason
(
fstatus
),
fstatus
&
AGG_TX_STATUS_MSK
,
fstatus
&
AGG_TX_TRY_MSK
);
}
}
...
...
@@ -1212,16 +1205,27 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
freed
++
;
}
WARN_ON
(
!
is_agg
&&
freed
!=
1
);
if
(
!
is_agg
&&
freed
!=
1
)
IWL_ERR
(
priv
,
"Q: %d, freed %d
\n
"
,
txq_id
,
freed
);
/*
* An offchannel frame can be send only on the AUX queue, where
* there is no aggregation (and reordering) so it only is single
* skb is expected to be processed.
*/
WARN_ON
(
is_offchannel_skb
&&
freed
!=
1
);
if
(
is_offchannel_skb
&&
freed
!=
1
)
IWL_ERR
(
priv
,
"OFFCHANNEL SKB freed %d
\n
"
,
freed
);
}
IWL_DEBUG_TX_REPLY
(
priv
,
"TXQ %d status %s (0x%08x)
\n
"
,
txq_id
,
iwl_get_tx_fail_reason
(
status
),
status
);
IWL_DEBUG_TX_REPLY
(
priv
,
"
\t\t\t\t
initial_rate 0x%x retries %d, idx=%d ssn=%d seq_ctl=0x%x
\n
"
,
le32_to_cpu
(
tx_resp
->
rate_n_flags
),
tx_resp
->
failure_frame
,
SEQ_TO_INDEX
(
sequence
),
ssn
,
le16_to_cpu
(
tx_resp
->
seq_ctl
));
iwl_check_abort_status
(
priv
,
tx_resp
->
frame_count
,
status
);
spin_unlock
(
&
priv
->
sta_lock
);
...
...
drivers/net/wireless/iwlwifi/iwl-fh.h
View file @
aa3c90b8
...
...
@@ -225,6 +225,8 @@ static inline unsigned int FH_MEM_CBBC_QUEUE(unsigned int chnl)
#define FH_RSCSR_CHNL0_RBDCB_WPTR_REG (FH_MEM_RSCSR_CHNL0 + 0x008)
#define FH_RSCSR_CHNL0_WPTR (FH_RSCSR_CHNL0_RBDCB_WPTR_REG)
#define FW_RSCSR_CHNL0_RXDCB_RDPTR_REG (FH_MEM_RSCSR_CHNL0 + 0x00c)
#define FH_RSCSR_CHNL0_RDPTR FW_RSCSR_CHNL0_RXDCB_RDPTR_REG
/**
* Rx Config/Status Registers (RCSR)
...
...
@@ -257,6 +259,8 @@ static inline unsigned int FH_MEM_CBBC_QUEUE(unsigned int chnl)
#define FH_MEM_RCSR_CHNL0 (FH_MEM_RCSR_LOWER_BOUND)
#define FH_MEM_RCSR_CHNL0_CONFIG_REG (FH_MEM_RCSR_CHNL0)
#define FH_MEM_RCSR_CHNL0_RBDCB_WPTR (FH_MEM_RCSR_CHNL0 + 0x8)
#define FH_MEM_RCSR_CHNL0_FLUSH_RB_REQ (FH_MEM_RCSR_CHNL0 + 0x10)
#define FH_RCSR_CHNL0_RX_CONFIG_RB_TIMEOUT_MSK (0x00000FF0)
/* bits 4-11 */
#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_MSK (0x00001000)
/* bits 12 */
...
...
drivers/net/wireless/iwlwifi/iwl-trans.h
View file @
aa3c90b8
...
...
@@ -307,6 +307,16 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r)
#define IWL_MAX_TID_COUNT 8
#define IWL_FRAME_LIMIT 64
/**
* enum iwl_wowlan_status - WoWLAN image/device status
* @IWL_D3_STATUS_ALIVE: firmware is still running after resume
* @IWL_D3_STATUS_RESET: device was reset while suspended
*/
enum
iwl_d3_status
{
IWL_D3_STATUS_ALIVE
,
IWL_D3_STATUS_RESET
,
};
/**
* struct iwl_trans_config - transport configuration
*
...
...
@@ -363,9 +373,12 @@ struct iwl_trans;
* May sleep
* @stop_device:stops the whole device (embedded CPU put to reset)
* May sleep
* @
wowlan
_suspend: put the device into the correct mode for WoWLAN during
* @
d3
_suspend: put the device into the correct mode for WoWLAN during
* suspend. This is optional, if not implemented WoWLAN will not be
* supported. This callback may sleep.
* @d3_resume: resume the device after WoWLAN, enabling the opmode to
* talk to the WoWLAN image to get its status. This is optional, if not
* implemented WoWLAN will not be supported. This callback may sleep.
* @send_cmd:send a host command. Must return -ERFKILL if RFkill is asserted.
* If RFkill is asserted in the middle of a SYNC host command, it must
* return -ERFKILL straight away.
...
...
@@ -391,7 +404,8 @@ struct iwl_trans;
* @read_prph: read a DWORD from a periphery register
* @write_prph: write a DWORD to a periphery register
* @read_mem: read device's SRAM in DWORD
* @write_mem: write device's SRAM in DWORD
* @write_mem: write device's SRAM in DWORD. If %buf is %NULL, then the memory
* will be zeroed.
* @configure: configure parameters required by the transport layer from
* the op_mode. May be called several times before start_fw, can't be
* called after that.
...
...
@@ -408,7 +422,8 @@ struct iwl_trans_ops {
void
(
*
fw_alive
)(
struct
iwl_trans
*
trans
,
u32
scd_addr
);
void
(
*
stop_device
)(
struct
iwl_trans
*
trans
);
void
(
*
wowlan_suspend
)(
struct
iwl_trans
*
trans
);
void
(
*
d3_suspend
)(
struct
iwl_trans
*
trans
);
int
(
*
d3_resume
)(
struct
iwl_trans
*
trans
,
enum
iwl_d3_status
*
status
);
int
(
*
send_cmd
)(
struct
iwl_trans
*
trans
,
struct
iwl_host_cmd
*
cmd
);
...
...
@@ -561,10 +576,17 @@ static inline void iwl_trans_stop_device(struct iwl_trans *trans)
trans
->
state
=
IWL_TRANS_NO_FW
;
}
static
inline
void
iwl_trans_wowlan_suspend
(
struct
iwl_trans
*
trans
)
static
inline
void
iwl_trans_d3_suspend
(
struct
iwl_trans
*
trans
)
{
might_sleep
();
trans
->
ops
->
d3_suspend
(
trans
);
}
static
inline
int
iwl_trans_d3_resume
(
struct
iwl_trans
*
trans
,
enum
iwl_d3_status
*
status
)
{
might_sleep
();
trans
->
ops
->
wowlan_suspend
(
tran
s
);
return
trans
->
ops
->
d3_resume
(
trans
,
statu
s
);
}
static
inline
int
iwl_trans_send_cmd
(
struct
iwl_trans
*
trans
,
...
...
drivers/net/wireless/iwlwifi/pcie/internal.h
View file @
aa3c90b8
...
...
@@ -357,6 +357,8 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans,
struct
iwl_rx_cmd_buffer
*
rxb
,
int
handler_status
);
void
iwl_trans_pcie_reclaim
(
struct
iwl_trans
*
trans
,
int
txq_id
,
int
ssn
,
struct
sk_buff_head
*
skbs
);
void
iwl_trans_pcie_tx_reset
(
struct
iwl_trans
*
trans
);
/*****************************************************
* Error handling
******************************************************/
...
...
drivers/net/wireless/iwlwifi/pcie/rx.c
View file @
aa3c90b8
...
...
@@ -436,7 +436,7 @@ static int iwl_pcie_rx_alloc(struct iwl_trans *trans)
err_rb_stts:
dma_free_coherent
(
dev
,
sizeof
(
__le32
)
*
RX_QUEUE_SIZE
,
rxq
->
bd
,
rxq
->
bd_dma
);
memset
(
&
rxq
->
bd_dma
,
0
,
sizeof
(
rxq
->
bd_dma
))
;
rxq
->
bd_dma
=
0
;
rxq
->
bd
=
NULL
;
err_bd:
return
-
ENOMEM
;
...
...
@@ -455,6 +455,10 @@ static void iwl_pcie_rx_hw_init(struct iwl_trans *trans, struct iwl_rxq *rxq)
/* Stop Rx DMA */
iwl_write_direct32
(
trans
,
FH_MEM_RCSR_CHNL0_CONFIG_REG
,
0
);
/* reset and flush pointers */
iwl_write_direct32
(
trans
,
FH_MEM_RCSR_CHNL0_RBDCB_WPTR
,
0
);
iwl_write_direct32
(
trans
,
FH_MEM_RCSR_CHNL0_FLUSH_RB_REQ
,
0
);
iwl_write_direct32
(
trans
,
FH_RSCSR_CHNL0_RDPTR
,
0
);
/* Reset driver's Rx queue write index */
iwl_write_direct32
(
trans
,
FH_RSCSR_CHNL0_RBDCB_WPTR_REG
,
0
);
...
...
@@ -491,7 +495,6 @@ int iwl_pcie_rx_init(struct iwl_trans *trans)
{
struct
iwl_trans_pcie
*
trans_pcie
=
IWL_TRANS_GET_PCIE_TRANS
(
trans
);
struct
iwl_rxq
*
rxq
=
&
trans_pcie
->
rxq
;
int
i
,
err
;
unsigned
long
flags
;
...
...
@@ -518,6 +521,7 @@ int iwl_pcie_rx_init(struct iwl_trans *trans)
rxq
->
read
=
rxq
->
write
=
0
;
rxq
->
write_actual
=
0
;
rxq
->
free_count
=
0
;
memset
(
rxq
->
rb_stts
,
0
,
sizeof
(
*
rxq
->
rb_stts
));
spin_unlock_irqrestore
(
&
rxq
->
lock
,
flags
);
iwl_pcie_rx_replenish
(
trans
);
...
...
@@ -553,7 +557,7 @@ void iwl_pcie_rx_free(struct iwl_trans *trans)
dma_free_coherent
(
trans
->
dev
,
sizeof
(
__le32
)
*
RX_QUEUE_SIZE
,
rxq
->
bd
,
rxq
->
bd_dma
);
memset
(
&
rxq
->
bd_dma
,
0
,
sizeof
(
rxq
->
bd_dma
))
;
rxq
->
bd_dma
=
0
;
rxq
->
bd
=
NULL
;
if
(
rxq
->
rb_stts
)
...
...
@@ -562,7 +566,7 @@ void iwl_pcie_rx_free(struct iwl_trans *trans)
rxq
->
rb_stts
,
rxq
->
rb_stts_dma
);
else
IWL_DEBUG_INFO
(
trans
,
"Free rxq->rb_stts which is NULL
\n
"
);
memset
(
&
rxq
->
rb_stts_dma
,
0
,
sizeof
(
rxq
->
rb_stts_dma
))
;
rxq
->
rb_stts_dma
=
0
;
rxq
->
rb_stts
=
NULL
;
}
...
...
drivers/net/wireless/iwlwifi/pcie/trans.c
View file @
aa3c90b8
...
...
@@ -75,18 +75,13 @@
#include "iwl-agn-hw.h"
#include "internal.h"
static
void
iwl_pcie_set_pwr
_vmain
(
struct
iwl_trans
*
trans
)
static
void
iwl_pcie_set_pwr
(
struct
iwl_trans
*
trans
,
bool
vaux
)
{
/*
* (for documentation purposes)
* to set power to V_AUX, do:
if (pci_pme_capable(priv->pci_dev, PCI_D3cold))
if
(
vaux
&&
pci_pme_capable
(
to_pci_dev
(
trans
->
dev
),
PCI_D3cold
))
iwl_set_bits_mask_prph
(
trans
,
APMG_PS_CTRL_REG
,
APMG_PS_CTRL_VAL_PWR_SRC_VAUX
,
~
APMG_PS_CTRL_MSK_PWR_SRC
);
*/
else
iwl_set_bits_mask_prph
(
trans
,
APMG_PS_CTRL_REG
,
APMG_PS_CTRL_VAL_PWR_SRC_VMAIN
,
~
APMG_PS_CTRL_MSK_PWR_SRC
);
...
...
@@ -259,7 +254,7 @@ static int iwl_pcie_nic_init(struct iwl_trans *trans)
spin_unlock_irqrestore
(
&
trans_pcie
->
irq_lock
,
flags
);
iwl_pcie_set_pwr
_vmain
(
trans
);
iwl_pcie_set_pwr
(
trans
,
false
);
iwl_op_mode_nic_config
(
trans
->
op_mode
);
...
...
@@ -545,15 +540,76 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
clear_bit
(
STATUS_RFKILL
,
&
trans_pcie
->
status
);
}
static
void
iwl_trans_pcie_
wowlan
_suspend
(
struct
iwl_trans
*
trans
)
static
void
iwl_trans_pcie_
d3
_suspend
(
struct
iwl_trans
*
trans
)
{
/* let the ucode operate on its own */
iwl_write32
(
trans
,
CSR_UCODE_DRV_GP1_SET
,
CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE
);
iwl_disable_interrupts
(
trans
);
iwl_pcie_disable_ict
(
trans
);
iwl_clear_bit
(
trans
,
CSR_GP_CNTRL
,
CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ
);
iwl_clear_bit
(
trans
,
CSR_GP_CNTRL
,
CSR_GP_CNTRL_REG_FLAG_INIT_DONE
);
/*
* reset TX queues -- some of their registers reset during S3
* so if we don't reset everything here the D3 image would try
* to execute some invalid memory upon resume
*/
iwl_trans_pcie_tx_reset
(
trans
);
iwl_pcie_set_pwr
(
trans
,
true
);
}
static
int
iwl_trans_pcie_d3_resume
(
struct
iwl_trans
*
trans
,
enum
iwl_d3_status
*
status
)
{
u32
val
;
int
ret
;
iwl_pcie_set_pwr
(
trans
,
false
);
val
=
iwl_read32
(
trans
,
CSR_RESET
);
if
(
val
&
CSR_RESET_REG_FLAG_NEVO_RESET
)
{
*
status
=
IWL_D3_STATUS_RESET
;
return
0
;
}
/*
* Also enables interrupts - none will happen as the device doesn't
* know we're waking it up, only when the opmode actually tells it
* after this call.
*/
iwl_pcie_reset_ict
(
trans
);
iwl_set_bit
(
trans
,
CSR_GP_CNTRL
,
CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ
);
iwl_set_bit
(
trans
,
CSR_GP_CNTRL
,
CSR_GP_CNTRL_REG_FLAG_INIT_DONE
);
ret
=
iwl_poll_bit
(
trans
,
CSR_GP_CNTRL
,
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY
,
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY
,
25000
);
if
(
ret
)
{
IWL_ERR
(
trans
,
"Failed to resume the device (mac ready)
\n
"
);
return
ret
;
}
iwl_trans_pcie_tx_reset
(
trans
);
ret
=
iwl_pcie_rx_init
(
trans
);
if
(
ret
)
{
IWL_ERR
(
trans
,
"Failed to resume the device (RX reset)
\n
"
);
return
ret
;
}
iwl_write32
(
trans
,
CSR_UCODE_DRV_GP1_CLR
,
CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE
);
*
status
=
IWL_D3_STATUS_ALIVE
;
return
0
;
}
static
int
iwl_trans_pcie_start_hw
(
struct
iwl_trans
*
trans
)
...
...
@@ -719,9 +775,6 @@ static int iwl_trans_pcie_resume(struct iwl_trans *trans)
hw_rfkill
=
iwl_is_rfkill_set
(
trans
);
iwl_op_mode_hw_rf_kill
(
trans
->
op_mode
,
hw_rfkill
);
if
(
!
hw_rfkill
)
iwl_enable_interrupts
(
trans
);
return
0
;
}
#endif
/* CONFIG_PM_SLEEP */
...
...
@@ -818,7 +871,8 @@ static int iwl_trans_pcie_write_mem(struct iwl_trans *trans, u32 addr,
if
(
iwl_trans_grab_nic_access
(
trans
,
false
))
{
iwl_write32
(
trans
,
HBUS_TARG_MEM_WADDR
,
addr
);
for
(
offs
=
0
;
offs
<
dwords
;
offs
++
)
iwl_write32
(
trans
,
HBUS_TARG_MEM_WDAT
,
vals
[
offs
]);
iwl_write32
(
trans
,
HBUS_TARG_MEM_WDAT
,
vals
?
vals
[
offs
]
:
0
);
iwl_trans_release_nic_access
(
trans
);
}
else
{
ret
=
-
EBUSY
;
...
...
@@ -836,6 +890,8 @@ static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans)
struct
iwl_queue
*
q
;
int
cnt
;
unsigned
long
now
=
jiffies
;
u32
scd_sram_addr
;
u8
buf
[
16
];
int
ret
=
0
;
/* waiting for all the tx frames complete might take a while */
...
...
@@ -849,11 +905,50 @@ static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans)
msleep
(
1
);
if
(
q
->
read_ptr
!=
q
->
write_ptr
)
{
IWL_ERR
(
trans
,
"fail to flush all tx fifo queues
\n
"
);
IWL_ERR
(
trans
,
"fail to flush all tx fifo queues Q %d
\n
"
,
cnt
);
ret
=
-
ETIMEDOUT
;
break
;
}
}
if
(
!
ret
)
return
0
;
IWL_ERR
(
trans
,
"Current SW read_ptr %d write_ptr %d
\n
"
,
txq
->
q
.
read_ptr
,
txq
->
q
.
write_ptr
);
scd_sram_addr
=
trans_pcie
->
scd_base_addr
+
SCD_TX_STTS_QUEUE_OFFSET
(
txq
->
q
.
id
);
iwl_trans_read_mem_bytes
(
trans
,
scd_sram_addr
,
buf
,
sizeof
(
buf
));
iwl_print_hex_error
(
trans
,
buf
,
sizeof
(
buf
));
for
(
cnt
=
0
;
cnt
<
FH_TCSR_CHNL_NUM
;
cnt
++
)
IWL_ERR
(
trans
,
"FH TRBs(%d) = 0x%08x
\n
"
,
cnt
,
iwl_read_direct32
(
trans
,
FH_TX_TRB_REG
(
cnt
)));
for
(
cnt
=
0
;
cnt
<
trans
->
cfg
->
base_params
->
num_of_queues
;
cnt
++
)
{
u32
status
=
iwl_read_prph
(
trans
,
SCD_QUEUE_STATUS_BITS
(
cnt
));
u8
fifo
=
(
status
>>
SCD_QUEUE_STTS_REG_POS_TXF
)
&
0x7
;
bool
active
=
!!
(
status
&
BIT
(
SCD_QUEUE_STTS_REG_POS_ACTIVE
));
u32
tbl_dw
=
iwl_trans_read_mem32
(
trans
,
trans_pcie
->
scd_base_addr
+
SCD_TRANS_TBL_OFFSET_QUEUE
(
cnt
));
if
(
cnt
&
0x1
)
tbl_dw
=
(
tbl_dw
&
0xFFFF0000
)
>>
16
;
else
tbl_dw
=
tbl_dw
&
0x0000FFFF
;
IWL_ERR
(
trans
,
"Q %d is %sactive and mapped to fifo %d ra_tid 0x%04x [%d,%d]
\n
"
,
cnt
,
active
?
""
:
"in"
,
fifo
,
tbl_dw
,
iwl_read_prph
(
trans
,
SCD_QUEUE_RDPTR
(
cnt
))
&
(
txq
->
q
.
n_bd
-
1
),
iwl_read_prph
(
trans
,
SCD_QUEUE_WRPTR
(
cnt
)));
}
return
ret
;
}
...
...
@@ -1281,7 +1376,8 @@ static const struct iwl_trans_ops trans_ops_pcie = {
.
start_fw
=
iwl_trans_pcie_start_fw
,
.
stop_device
=
iwl_trans_pcie_stop_device
,
.
wowlan_suspend
=
iwl_trans_pcie_wowlan_suspend
,
.
d3_suspend
=
iwl_trans_pcie_d3_suspend
,
.
d3_resume
=
iwl_trans_pcie_d3_resume
,
.
send_cmd
=
iwl_trans_pcie_send_hcmd
,
...
...
drivers/net/wireless/iwlwifi/pcie/tx.c
View file @
aa3c90b8
...
...
@@ -309,6 +309,9 @@ void iwl_pcie_txq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_txq *txq)
return
;
}
IWL_DEBUG_TX
(
trans
,
"Q:%d WR: 0x%x
\n
"
,
txq_id
,
txq
->
q
.
write_ptr
);
iwl_write_direct32
(
trans
,
HBUS_TARG_WRPTR
,
txq
->
q
.
write_ptr
|
(
txq_id
<<
8
));
...
...
@@ -615,7 +618,7 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id)
if
(
txq
->
q
.
n_bd
)
{
dma_free_coherent
(
dev
,
sizeof
(
struct
iwl_tfd
)
*
txq
->
q
.
n_bd
,
txq
->
tfds
,
txq
->
q
.
dma_addr
);
memset
(
&
txq
->
q
.
dma_addr
,
0
,
sizeof
(
txq
->
q
.
dma_addr
))
;
txq
->
q
.
dma_addr
=
0
;
}
kfree
(
txq
->
entries
);
...
...
@@ -641,9 +644,11 @@ static void iwl_pcie_txq_set_sched(struct iwl_trans *trans, u32 mask)
void
iwl_pcie_tx_start
(
struct
iwl_trans
*
trans
,
u32
scd_base_addr
)
{
struct
iwl_trans_pcie
*
trans_pcie
=
IWL_TRANS_GET_PCIE_TRANS
(
trans
);
u32
a
;
int
nq
=
trans
->
cfg
->
base_params
->
num_of_queues
;
int
chan
;
u32
reg_val
;
int
clear_dwords
=
(
SCD_TRANS_TBL_OFFSET_QUEUE
(
nq
)
-
SCD_CONTEXT_MEM_LOWER_BOUND
)
/
sizeof
(
u32
);
/* make sure all queue are not stopped/used */
memset
(
trans_pcie
->
queue_stopped
,
0
,
sizeof
(
trans_pcie
->
queue_stopped
));
...
...
@@ -655,20 +660,10 @@ void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr)
WARN_ON
(
scd_base_addr
!=
0
&&
scd_base_addr
!=
trans_pcie
->
scd_base_addr
);
a
=
trans_pcie
->
scd_base_addr
+
SCD_CONTEXT_MEM_LOWER_BOUND
;
/* reset conext data memory */
for
(;
a
<
trans_pcie
->
scd_base_addr
+
SCD_CONTEXT_MEM_UPPER_BOUND
;
a
+=
4
)
iwl_trans_write_mem32
(
trans
,
a
,
0
);
/* reset tx status memory */
for
(;
a
<
trans_pcie
->
scd_base_addr
+
SCD_TX_STTS_MEM_UPPER_BOUND
;
a
+=
4
)
iwl_trans_write_mem32
(
trans
,
a
,
0
);
for
(;
a
<
trans_pcie
->
scd_base_addr
+
SCD_TRANS_TBL_OFFSET_QUEUE
(
trans
->
cfg
->
base_params
->
num_of_queues
);
a
+=
4
)
iwl_trans_write_mem32
(
trans
,
a
,
0
);
/* reset context data, TX status and translation data */
iwl_trans_write_mem
(
trans
,
trans_pcie
->
scd_base_addr
+
SCD_CONTEXT_MEM_LOWER_BOUND
,
NULL
,
clear_dwords
);
iwl_write_prph
(
trans
,
SCD_DRAM_BASE_ADDR
,
trans_pcie
->
scd_bc_tbls
.
dma
>>
10
);
...
...
@@ -700,6 +695,29 @@ void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr)
APMG_PCIDEV_STT_VAL_L1_ACT_DIS
);
}
void
iwl_trans_pcie_tx_reset
(
struct
iwl_trans
*
trans
)
{
struct
iwl_trans_pcie
*
trans_pcie
=
IWL_TRANS_GET_PCIE_TRANS
(
trans
);
int
txq_id
;
for
(
txq_id
=
0
;
txq_id
<
trans
->
cfg
->
base_params
->
num_of_queues
;
txq_id
++
)
{
struct
iwl_txq
*
txq
=
&
trans_pcie
->
txq
[
txq_id
];
iwl_write_direct32
(
trans
,
FH_MEM_CBBC_QUEUE
(
txq_id
),
txq
->
q
.
dma_addr
>>
8
);
iwl_pcie_txq_unmap
(
trans
,
txq_id
);
txq
->
q
.
read_ptr
=
0
;
txq
->
q
.
write_ptr
=
0
;
}
/* Tell NIC where to find the "keep warm" buffer */
iwl_write_direct32
(
trans
,
FH_KW_MEM_ADDR_REG
,
trans_pcie
->
kw
.
dma
>>
4
);
iwl_pcie_tx_start
(
trans
,
trans_pcie
->
scd_base_addr
);
}
/*
* iwl_pcie_tx_stop - Stop all Tx DMA channels
*/
...
...
@@ -1645,10 +1663,6 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
tx_cmd
->
dram_lsb_ptr
=
cpu_to_le32
(
scratch_phys
);
tx_cmd
->
dram_msb_ptr
=
iwl_get_dma_hi_addr
(
scratch_phys
);
IWL_DEBUG_TX
(
trans
,
"sequence nr = 0X%x
\n
"
,
le16_to_cpu
(
dev_cmd
->
hdr
.
sequence
));
IWL_DEBUG_TX
(
trans
,
"tx_flags = 0X%x
\n
"
,
le32_to_cpu
(
tx_cmd
->
tx_flags
));
/* Set up entry for this TFD in Tx byte-count array */
iwl_pcie_txq_update_byte_cnt_tbl
(
trans
,
txq
,
le16_to_cpu
(
tx_cmd
->
len
));
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment