* [ath9k-devel] About reg.h
@ 2011-11-26 14:49 Cheung Hiu Fung
2011-11-26 20:53 ` Adrian Chadd
0 siblings, 1 reply; 10+ messages in thread
From: Cheung Hiu Fung @ 2011-11-26 14:49 UTC (permalink / raw)
To: ath9k-devel
Hi all,
I have some queustion related to reg.h . For example,
#define AR_QOS_NO_ACK_TWO_BIT 0x0000000f
#define AR_QOS_NO_ACK_TWO_BIT_S 0
I guess the first one is the memeory location for a buffer. What is the
meaning of next definition?
I am trying to modify the header of some data buffer.
REG_WRITE(ah, AR_QOS_NO_ACK,
SM(2, AR_QOS_NO_ACK_TWO_BIT) |
SM(5, AR_QOS_NO_ACK_BIT_OFF) |
SM(0, AR_QOS_NO_ACK_BYTE_OFF));
I think reg_wirte should be used for writing the header for a frame.
but I am not sure SM(2, AR_QOS_NO_ACK_TWO_BIT) meaning. Can anyone give a
brief explaination? Thanks
Regards,
Jax
^ permalink raw reply [flat|nested] 10+ messages in thread
* [ath9k-devel] About reg.h
2011-11-26 14:49 [ath9k-devel] About reg.h Cheung Hiu Fung
@ 2011-11-26 20:53 ` Adrian Chadd
2011-11-27 2:44 ` Cheung Hiu Fung
0 siblings, 1 reply; 10+ messages in thread
From: Adrian Chadd @ 2011-11-26 20:53 UTC (permalink / raw)
To: ath9k-devel
The best thing to do is look at the definitions of those macros.
For the above, there is the field definition (ie a mask telling you
which bits are involved) and then the field shift (ie, how many bits
you need to shift a value left or right to get it into the right
"spot" to match the field definition.)
SM(val, field) will take the value, shift it to the left by field_S
and masks it with the field. This lets you take a value and shift it
into position to write into a register field.
MS(reg, field) takes the register value, masks it with the field, then
shifts it to the right. This lets you take a field from a register and
return its value.
Adrian
^ permalink raw reply [flat|nested] 10+ messages in thread
* [ath9k-devel] About reg.h
2011-11-26 20:53 ` Adrian Chadd
@ 2011-11-27 2:44 ` Cheung Hiu Fung
2011-11-27 3:50 ` Adrian Chadd
0 siblings, 1 reply; 10+ messages in thread
From: Cheung Hiu Fung @ 2011-11-27 2:44 UTC (permalink / raw)
To: ath9k-devel
Thanks for help. But I have some place that i am not clear. Take this for
an example.
#define AR_MIC_QOS_CONTROL 0x8118
#define AR_MIC_QOS_SELECT 0x811c
#define AR_QOS_NO_ACK 0x8108
#define AR_QOS_NO_ACK_TWO_BIT 0x0000000f
#define AR_QOS_NO_ACK_TWO_BIT_S 0
#define AR_QOS_NO_ACK_BIT_OFF 0x00000070
#define AR_QOS_NO_ACK_BIT_OFF_S 4
#define AR_QOS_NO_ACK_BYTE_OFF 0x00000180
#define AR_QOS_NO_ACK_BYTE_OFF_S 7
static void ath9k_hw_init_qos(struct ath_hw *ah)
{
ENABLE_REGWRITE_BUFFER(ah);
REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa);
REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210);
REG_WRITE(ah, AR_QOS_NO_ACK,
SM(2, AR_QOS_NO_ACK_TWO_BIT) |
SM(5, AR_QOS_NO_ACK_BIT_OFF) |
SM(0, AR_QOS_NO_ACK_BYTE_OFF));
REGWRITE_BUFFER_FLUSH(ah);
}
For the first two REG_WRITE. Is that ah is the header, and the REG_WRITE
sstart to write starting from memory space "8118" and fill with 100aa?
And I am still not quiet sure how the third one work. Thanks for help.
Regards,
Jax
> The best thing to do is look at the definitions of those macros.
>
> For the above, there is the field definition (ie a mask telling you
> which bits are involved) and then the field shift (ie, how many bits
> you need to shift a value left or right to get it into the right
> "spot" to match the field definition.)
>
> SM(val, field) will take the value, shift it to the left by field_S
> and masks it with the field. This lets you take a value and shift it
> into position to write into a register field.
>
> MS(reg, field) takes the register value, masks it with the field, then
> shifts it to the right. This lets you take a field from a register and
> return its value.
>
>
>
> Adrian
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* [ath9k-devel] About reg.h
2011-11-27 2:44 ` Cheung Hiu Fung
@ 2011-11-27 3:50 ` Adrian Chadd
2011-11-27 14:05 ` Cheung Hiu Fung
0 siblings, 1 reply; 10+ messages in thread
From: Adrian Chadd @ 2011-11-27 3:50 UTC (permalink / raw)
To: ath9k-devel
On 27 November 2011 10:44, Cheung Hiu Fung <phjay@ust.hk> wrote:
> Thanks for help. But I have some place that i am not clear. Take this for
> an example.
>
> #define AR_MIC_QOS_CONTROL 0x8118
> #define AR_MIC_QOS_SELECT ?0x811c
These are registers.
> #define AR_QOS_NO_ACK ? ? ? ? ? ? ?0x8108
This is a register.
> #define AR_QOS_NO_ACK_TWO_BIT ? ? ?0x0000000f
> #define AR_QOS_NO_ACK_TWO_BIT_S ? ?0
This is a bitfield.
> #define AR_QOS_NO_ACK_BIT_OFF ? ? ?0x00000070
> #define AR_QOS_NO_ACK_BIT_OFF_S ? ?4
This is a bitfield.
> #define AR_QOS_NO_ACK_BYTE_OFF ? ? 0x00000180
> #define AR_QOS_NO_ACK_BYTE_OFF_S ? 7
This is a bitfield.
> static void ath9k_hw_init_qos(struct ath_hw *ah)
> {
> ? ? ? ?ENABLE_REGWRITE_BUFFER(ah);
>
> ? ? ? ?REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa);
> ? ? ? ?REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210);
These are self-explanatory.
> ? ? ? ?REG_WRITE(ah, AR_QOS_NO_ACK,
> ? ? ? ? ? ? ? ? ?SM(2, AR_QOS_NO_ACK_TWO_BIT) |
> ? ? ? ? ? ? ? ? ?SM(5, AR_QOS_NO_ACK_BIT_OFF) |
> ? ? ? ? ? ? ? ? ?SM(0, AR_QOS_NO_ACK_BYTE_OFF));
>
> ? ? ? ?REGWRITE_BUFFER_FLUSH(ah);
> }
>
> For the first two REG_WRITE. Is that ah is the header, and the REG_WRITE
> sstart to write starting from memory space "8118" and fill with 100aa?
REG_WRITE says "just write this value to this location." So register
0x8118 == 0x000100aa.
It doesn't touch any memory outside of that - just that 32-bit
register. Technically speaking, it fills 0x8118,8119,811a,811b with
the relevant 8 bit words via a single 32 bit write, as the register
space are all 32 bit words. So there's no direct access of 8119, 811a,
811b. Hopefully you understand that. :)
> And I am still not quiet sure how the third one work. Thanks for help.
The third does the following:
> REG_WRITE(ah, AR_QOS_NO_ACK,
Write the following value to AR_QOS_NO_ACK:
> SM(2, AR_QOS_NO_ACK_TWO_BIT) |
(2 << 0) & 0xf
> SM(5, AR_QOS_NO_ACK_BIT_OFF) |
(5 << 4) & 0x70
> SM(0, AR_QOS_NO_ACK_BYTE_OFF));
(0 << 7) & 0x180
Now, these three values are OR'ed together before being written to the register.
Now, the 32 bit register AR_QOS_NO_ACK has (at least) three fields:
* NO_ACK_TWO_BIT: which takes bits 0->3;
* NO_ACK_BIT_OFF: which takes bits 4-6;
* NO_ACK_BYTE_OFF: which takes bits 7-8.
The SM macro lets you write values to that register field by taking care of:
* shifting the value into place (the field_S value);
* masking out bits which aren't relevant to that particular field, so
you don't shift a value that's too big for the field and thus
overwrites other bits (the field value, which is actually a mask).
I hope that makes more sense. If it doesn't, please stare at some
freely available datasheets (eg for the AVR microcontrollers) and see
how those registers are laid out, then figure out how you'd write code
to set the relevant bits in those registers.
HTH,
Adrian
^ permalink raw reply [flat|nested] 10+ messages in thread
* [ath9k-devel] About reg.h
2011-11-27 3:50 ` Adrian Chadd
@ 2011-11-27 14:05 ` Cheung Hiu Fung
2011-11-27 14:26 ` Adrian Chadd
0 siblings, 1 reply; 10+ messages in thread
From: Cheung Hiu Fung @ 2011-11-27 14:05 UTC (permalink / raw)
To: ath9k-devel
Thanks for your clear explaination. I am still not quiet sure. So in this
case. "250" is written in QoS field. Is that right or wrong? If yes then
it is equal to "1001010000"
http://www.eefocus.com/article/08-06/43509s.html
according to this link (table7-6) . The bit5 and bit 6 is set for ACK
policy. I mean this is set to be "01" for no ACK. But when I compile the
driver and use simple programing to send some packet. The wireshark show
this packet is set to be "normal ack", although the program didn't have
response with transmitting any ACK. I am not sure why. I guess it should
be "00". Or I misunderstand what u said?
Or this ath9k_hw_init_qos have nothing to do with "filling information to
mac header", is that just an initialization for register memory
allocation? I cannot find any other file that try to fill that QoS header.
Thanks for help.
Regrads,
Jax
> On 27 November 2011 10:44, Cheung Hiu Fung <phjay@ust.hk> wrote:
>> Thanks for help. But I have some place that i am not clear. Take this
>> for
>> an example.
>>
>> #define AR_MIC_QOS_CONTROL 0x8118
>> #define AR_MIC_QOS_SELECT ?0x811c
>
> These are registers.
>
>> #define AR_QOS_NO_ACK ? ? ? ? ? ? ?0x8108
>
> This is a register.
>
>> #define AR_QOS_NO_ACK_TWO_BIT ? ? ?0x0000000f
>> #define AR_QOS_NO_ACK_TWO_BIT_S ? ?0
>
> This is a bitfield.
>
>> #define AR_QOS_NO_ACK_BIT_OFF ? ? ?0x00000070
>> #define AR_QOS_NO_ACK_BIT_OFF_S ? ?4
>
> This is a bitfield.
>
>> #define AR_QOS_NO_ACK_BYTE_OFF ? ? 0x00000180
>> #define AR_QOS_NO_ACK_BYTE_OFF_S ? 7
>
> This is a bitfield.
>
>> static void ath9k_hw_init_qos(struct ath_hw *ah)
>> {
>> ? ? ? ?ENABLE_REGWRITE_BUFFER(ah);
>>
>> ? ? ? ?REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa);
>> ? ? ? ?REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210);
>
> These are self-explanatory.
>
>> ? ? ? ?REG_WRITE(ah, AR_QOS_NO_ACK,
>> ? ? ? ? ? ? ? ? ?SM(2, AR_QOS_NO_ACK_TWO_BIT) |
>> ? ? ? ? ? ? ? ? ?SM(5, AR_QOS_NO_ACK_BIT_OFF) |
>> ? ? ? ? ? ? ? ? ?SM(0, AR_QOS_NO_ACK_BYTE_OFF));
>>
>> ? ? ? ?REGWRITE_BUFFER_FLUSH(ah);
>> }
>>
>> For the first two REG_WRITE. Is that ah is the header, and the REG_WRITE
>> sstart to write starting from memory space "8118" and fill with 100aa?
>
> REG_WRITE says "just write this value to this location." So register
> 0x8118 == 0x000100aa.
> It doesn't touch any memory outside of that - just that 32-bit
> register. Technically speaking, it fills 0x8118,8119,811a,811b with
> the relevant 8 bit words via a single 32 bit write, as the register
> space are all 32 bit words. So there's no direct access of 8119, 811a,
> 811b. Hopefully you understand that. :)
>
>> And I am still not quiet sure how the third one work. Thanks for help.
>
> The third does the following:
>
>> REG_WRITE(ah, AR_QOS_NO_ACK,
>
> Write the following value to AR_QOS_NO_ACK:
>
>> SM(2, AR_QOS_NO_ACK_TWO_BIT) |
>
> (2 << 0) & 0xf
>
>> SM(5, AR_QOS_NO_ACK_BIT_OFF) |
>
> (5 << 4) & 0x70
>
>> SM(0, AR_QOS_NO_ACK_BYTE_OFF));
>
> (0 << 7) & 0x180
>
> Now, these three values are OR'ed together before being written to the
> register.
>
> Now, the 32 bit register AR_QOS_NO_ACK has (at least) three fields:
>
> * NO_ACK_TWO_BIT: which takes bits 0->3;
> * NO_ACK_BIT_OFF: which takes bits 4-6;
> * NO_ACK_BYTE_OFF: which takes bits 7-8.
>
> The SM macro lets you write values to that register field by taking care
> of:
>
> * shifting the value into place (the field_S value);
> * masking out bits which aren't relevant to that particular field, so
> you don't shift a value that's too big for the field and thus
> overwrites other bits (the field value, which is actually a mask).
>
> I hope that makes more sense. If it doesn't, please stare at some
> freely available datasheets (eg for the AVR microcontrollers) and see
> how those registers are laid out, then figure out how you'd write code
> to set the relevant bits in those registers.
>
> HTH,
>
>
> Adrian
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* [ath9k-devel] About reg.h
2011-11-27 14:05 ` Cheung Hiu Fung
@ 2011-11-27 14:26 ` Adrian Chadd
2011-11-27 15:08 ` Cheung Hiu Fung
0 siblings, 1 reply; 10+ messages in thread
From: Adrian Chadd @ 2011-11-27 14:26 UTC (permalink / raw)
To: ath9k-devel
On 27 November 2011 22:05, Cheung Hiu Fung <phjay@ust.hk> wrote:
> Thanks for your clear explaination. I am still not quiet sure. So in this
> case. "250" is written in QoS field. Is that right or wrong? ?If yes then
> it is equal to "1001010000"
>
> http://www.eefocus.com/article/08-06/43509s.html
>
> according to this link (table7-6) . The bit5 and bit 6 is set for ACK
> policy. I mean this is set to be "01" for no ACK. But when I compile the
> driver and use simple programing to send some packet. The wireshark show
> this packet is set to be "normal ack", although the program didn't have
> response with transmitting any ACK. I am not sure why. I guess it should
> be "00". Or I misunderstand what u said?
That register doesn't control the ACK policy. It is completely
different and not relevant to what you're doing.
You can change whether a frame requires an ACK by setting the right
bit in the TX descriptor. There's a bit which controls whether the
frame requires an ACK from the remote side or not.
Adrian
^ permalink raw reply [flat|nested] 10+ messages in thread
* [ath9k-devel] About reg.h
2011-11-27 14:26 ` Adrian Chadd
@ 2011-11-27 15:08 ` Cheung Hiu Fung
2011-11-27 15:10 ` Adrian Chadd
0 siblings, 1 reply; 10+ messages in thread
From: Cheung Hiu Fung @ 2011-11-27 15:08 UTC (permalink / raw)
To: ath9k-devel
Thanks for reply. Is that I should set it at htc_drv_txrx.c?? I i saw
there is a void called
ath9k_htc_tx_data(struct ath9k_htc_priv *priv,
struct ieee80211_vif *vif,
struct sk_buff *skb,
u8 sta_idx, u8 vif_idx, u8 slot,
bool is_cab)
and inside the funtion
if (ieee80211_is_data_qos(hdr->frame_control)) {
qc = ieee80211_get_qos_ctl(hdr);
tx_hdr.tidno = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
}
or did i locate the wrong places again? I am not sure where is the
function that used for write header. My target is to modify the driver
that all data "QoS to be no ack". And I am still not quiet sure how to
achieve it.
Thanks for your help.
Regards,
Jax
> On 27 November 2011 22:05, Cheung Hiu Fung <phjay@ust.hk> wrote:
>> Thanks for your clear explaination. I am still not quiet sure. So in
>> this
>> case. "250" is written in QoS field. Is that right or wrong? ?If yes
>> then
>> it is equal to "1001010000"
>>
>> http://www.eefocus.com/article/08-06/43509s.html
>>
>> according to this link (table7-6) . The bit5 and bit 6 is set for ACK
>> policy. I mean this is set to be "01" for no ACK. But when I compile the
>> driver and use simple programing to send some packet. The wireshark show
>> this packet is set to be "normal ack", although the program didn't have
>> response with transmitting any ACK. I am not sure why. I guess it should
>> be "00". Or I misunderstand what u said?
>
> That register doesn't control the ACK policy. It is completely
> different and not relevant to what you're doing.
>
> You can change whether a frame requires an ACK by setting the right
> bit in the TX descriptor. There's a bit which controls whether the
> frame requires an ACK from the remote side or not.
>
>
>
> Adrian
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* [ath9k-devel] About reg.h
2011-11-27 15:08 ` Cheung Hiu Fung
@ 2011-11-27 15:10 ` Adrian Chadd
2011-11-27 15:30 ` Cheung Hiu Fung
0 siblings, 1 reply; 10+ messages in thread
From: Adrian Chadd @ 2011-11-27 15:10 UTC (permalink / raw)
To: ath9k-devel
You're in the right spot. Look at what ieee80211 flags are passed in
to the TX function, one of them (i think) is labelled NOACK or
similar.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [ath9k-devel] About reg.h
2011-11-27 15:10 ` Adrian Chadd
@ 2011-11-27 15:30 ` Cheung Hiu Fung
2011-11-28 0:22 ` Adrian Chadd
0 siblings, 1 reply; 10+ messages in thread
From: Cheung Hiu Fung @ 2011-11-27 15:30 UTC (permalink / raw)
To: ath9k-devel
Thanks for reply. I am still not sure how to do it. In htc_drv_txrx.c ,
static void ath9k_htc_tx_data
i saw after the function set all memory of header equal to 0 by
memset(&tx_hdr, 0, sizeof(struct tx_frame_hdr));
and the function try to set the qos value
if (ieee80211_is_data_qos(hdr->frame_control)) {
qc = ieee80211_get_qos_ctl(hdr);
tx_hdr.tidno = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
}
i try to seatch where is it define. then i come to xmit.c
void setup_frame_info
if (an && ieee80211_is_data_qos(hdr->frame_control) &&
conf_is_ht(&hw->conf) && (sc->sc_flags & SC_OP_TXAGGR)) {
tidno = ieee80211_get_qos_ctl(hdr)[0] & FF;
and i get lost there and don't know what to do next. My programming is not
in advanced level. Can u give me some guideline that what should be next
step? Thanks for help
Regards,
Jax
> You're in the right spot. Look at what ieee80211 flags are passed in
> to the TX function, one of them (i think) is labelled NOACK or
> similar.
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* [ath9k-devel] About reg.h
2011-11-27 15:30 ` Cheung Hiu Fung
@ 2011-11-28 0:22 ` Adrian Chadd
0 siblings, 0 replies; 10+ messages in thread
From: Adrian Chadd @ 2011-11-28 0:22 UTC (permalink / raw)
To: ath9k-devel
Ok, let's see.
Look at ath_tx_fill_desc() in xmit.c:
if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
info.flags |= ATH9K_TXDESC_NOACK;
That function sets up the bits needed to pass into
ath9k_hw_set_txdesc(), which then sets the TX descriptor fields based
on what's in 'info'.
I don't know if HTC has the same field. You may be right, it may just
be the QoS header that is programmed like that, and the HTC firmware
running on the USB NIC's CPU inspects that and sets the relevant bit
in the TX descriptor. (I'm looking at ath9k_htc_tx_data() and
ath9k_htc_tx_mgmt().)
So how about you take a look at what is in the frame being sent to
those functions and see if they have the QoS bit set, then flip on or
off the ACK required bit?
I think you'll have to do it in ath9k_htc_tx_data(). Just keep in mind
if you do that, I think you have to disable AMPDU for that frame (set
the packet data type to normal, not ampdu, read ath9k_htc_tx_data() to
see what I mean.)
Good luck!
Adrian
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2011-11-28 0:22 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-11-26 14:49 [ath9k-devel] About reg.h Cheung Hiu Fung
2011-11-26 20:53 ` Adrian Chadd
2011-11-27 2:44 ` Cheung Hiu Fung
2011-11-27 3:50 ` Adrian Chadd
2011-11-27 14:05 ` Cheung Hiu Fung
2011-11-27 14:26 ` Adrian Chadd
2011-11-27 15:08 ` Cheung Hiu Fung
2011-11-27 15:10 ` Adrian Chadd
2011-11-27 15:30 ` Cheung Hiu Fung
2011-11-28 0:22 ` Adrian Chadd
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).