Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 90305
b: refs/heads/master
c: 17e476b
h: refs/heads/master
i:
  90303: 49c8bc5
v: v3
  • Loading branch information
Emmanuel Grumbach authored and John W. Linville committed Mar 25, 2008
1 parent ddb120d commit 22b1077
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: deb09c435e3f947f8b2c9d5df6a9c0a5b472b125
refs/heads/master: 17e476b8db13790c03e2c46d93abc71468fca47e
9 changes: 9 additions & 0 deletions trunk/drivers/net/wireless/iwlwifi/iwl-4965-commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -890,13 +890,22 @@ struct iwl4965_rx_frame_hdr {
#define RX_RES_STATUS_SEC_TYPE_WEP (0x1 << 8)
#define RX_RES_STATUS_SEC_TYPE_CCMP (0x2 << 8)
#define RX_RES_STATUS_SEC_TYPE_TKIP (0x3 << 8)
#define RX_RES_STATUS_SEC_TYPE_ERR (0x7 << 8)

#define RX_RES_STATUS_STATION_FOUND (1<<6)
#define RX_RES_STATUS_NO_STATION_INFO_MISMATCH (1<<7)

#define RX_RES_STATUS_DECRYPT_TYPE_MSK (0x3 << 11)
#define RX_RES_STATUS_NOT_DECRYPT (0x0 << 11)
#define RX_RES_STATUS_DECRYPT_OK (0x3 << 11)
#define RX_RES_STATUS_BAD_ICV_MIC (0x1 << 11)
#define RX_RES_STATUS_BAD_KEY_TTAK (0x2 << 11)

#define RX_MPDU_RES_STATUS_ICV_OK (0x20)
#define RX_MPDU_RES_STATUS_MIC_OK (0x40)
#define RX_MPDU_RES_STATUS_TTAK_OK (1 << 7)
#define RX_MPDU_RES_STATUS_DEC_DONE_MSK (0x800)

struct iwl4965_rx_frame_end {
__le32 status;
__le64 timestamp;
Expand Down
66 changes: 66 additions & 0 deletions trunk/drivers/net/wireless/iwlwifi/iwl-4965.c
Original file line number Diff line number Diff line change
Expand Up @@ -3393,6 +3393,65 @@ static void iwl_update_rx_stats(struct iwl_priv *priv, u16 fc, u16 len)
priv->rx_stats[idx].bytes += len;
}

static u32 iwl4965_translate_rx_status(u32 decrypt_in)
{
u32 decrypt_out = 0;

if ((decrypt_in & RX_RES_STATUS_STATION_FOUND) ==
RX_RES_STATUS_STATION_FOUND)
decrypt_out |= (RX_RES_STATUS_STATION_FOUND |
RX_RES_STATUS_NO_STATION_INFO_MISMATCH);

decrypt_out |= (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK);

/* packet was not encrypted */
if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) ==
RX_RES_STATUS_SEC_TYPE_NONE)
return decrypt_out;

/* packet was encrypted with unknown alg */
if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) ==
RX_RES_STATUS_SEC_TYPE_ERR)
return decrypt_out;

/* decryption was not done in HW */
if ((decrypt_in & RX_MPDU_RES_STATUS_DEC_DONE_MSK) !=
RX_MPDU_RES_STATUS_DEC_DONE_MSK)
return decrypt_out;

switch (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) {

case RX_RES_STATUS_SEC_TYPE_CCMP:
/* alg is CCM: check MIC only */
if (!(decrypt_in & RX_MPDU_RES_STATUS_MIC_OK))
/* Bad MIC */
decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC;
else
decrypt_out |= RX_RES_STATUS_DECRYPT_OK;

break;

case RX_RES_STATUS_SEC_TYPE_TKIP:
if (!(decrypt_in & RX_MPDU_RES_STATUS_TTAK_OK)) {
/* Bad TTAK */
decrypt_out |= RX_RES_STATUS_BAD_KEY_TTAK;
break;
}
/* fall through if TTAK OK */
default:
if (!(decrypt_in & RX_MPDU_RES_STATUS_ICV_OK))
decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC;
else
decrypt_out |= RX_RES_STATUS_DECRYPT_OK;
break;
};

IWL_DEBUG_RX("decrypt_in:0x%x decrypt_out = 0x%x\n",
decrypt_in, decrypt_out);

return decrypt_out;
}

static void iwl4965_handle_data_packet(struct iwl_priv *priv, int is_data,
int include_phy,
struct iwl4965_rx_mem_buffer *rxb,
Expand All @@ -3406,6 +3465,7 @@ static void iwl4965_handle_data_packet(struct iwl_priv *priv, int is_data,
__le32 *rx_end;
unsigned int skblen;
u32 ampdu_status;
u32 ampdu_status_legacy;

if (!include_phy && priv->last_phy_res[0])
rx_start = (struct iwl4965_rx_phy_res *)&priv->last_phy_res[1];
Expand Down Expand Up @@ -3442,6 +3502,12 @@ static void iwl4965_handle_data_packet(struct iwl_priv *priv, int is_data,
ampdu_status = le32_to_cpu(*rx_end);
skblen = ((u8 *) rx_end - (u8 *) & pkt->u.raw[0]) + sizeof(u32);

if (!include_phy) {
/* New status scheme, need to translate */
ampdu_status_legacy = ampdu_status;
ampdu_status = iwl4965_translate_rx_status(ampdu_status);
}

/* start from MAC */
skb_reserve(rxb->skb, (void *)hdr - (void *)pkt);
skb_put(rxb->skb, len); /* end where data ends */
Expand Down
6 changes: 6 additions & 0 deletions trunk/drivers/net/wireless/iwlwifi/iwl4965-base.c
Original file line number Diff line number Diff line change
Expand Up @@ -2856,6 +2856,12 @@ void iwl4965_set_decrypted_flag(struct iwl_priv *priv, struct sk_buff *skb,
IWL_DEBUG_RX("decrypt_res:0x%x\n", decrypt_res);
switch (decrypt_res & RX_RES_STATUS_SEC_TYPE_MSK) {
case RX_RES_STATUS_SEC_TYPE_TKIP:
/* The uCode has got a bad phase 1 Key, pushes the packet.
* Decryption will be done in SW. */
if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) ==
RX_RES_STATUS_BAD_KEY_TTAK)
break;

if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) ==
RX_RES_STATUS_BAD_ICV_MIC)
stats->flag |= RX_FLAG_MMIC_ERROR;
Expand Down

0 comments on commit 22b1077

Please sign in to comment.