aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2008-05-04 22:22:34 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-05-14 16:29:45 -0400
commit133636deffc86809f59a0c8b768408d13237a9a2 (patch)
tree2c1d156db37f33ad9dd7eb311c6977d2948e9277 /drivers
parentdb11d6343aa14ab61258bfad9178042d4be49333 (diff)
iwlwifi: generalize iwl4965_send_add_station function
This patch moves iwl4965_send_add_station to iwlcore under new name iwl_send_add_sta. Function uses build command handler in order to support multiple HWs. Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c28
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h46
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h10
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c54
-rw-r--r--drivers/net/wireless/iwlwifi/iwl4965-base.c51
6 files changed, 127 insertions, 63 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index f7e267e30ce6..0644e22fe780 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -2931,7 +2931,7 @@ static void iwl4965_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
2931 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 2931 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
2932 spin_unlock_irqrestore(&priv->sta_lock, flags); 2932 spin_unlock_irqrestore(&priv->sta_lock, flags);
2933 2933
2934 iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC); 2934 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
2935} 2935}
2936 2936
2937static void iwl4965_update_ps_mode(struct iwl_priv *priv, u16 ps_bit, u8 *addr) 2937static void iwl4965_update_ps_mode(struct iwl_priv *priv, u16 ps_bit, u8 *addr)
@@ -3323,7 +3323,7 @@ static void iwl4965_sta_modify_enable_tid_tx(struct iwl_priv *priv,
3323 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 3323 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
3324 spin_unlock_irqrestore(&priv->sta_lock, flags); 3324 spin_unlock_irqrestore(&priv->sta_lock, flags);
3325 3325
3326 iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC); 3326 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
3327} 3327}
3328 3328
3329/** 3329/**
@@ -3878,7 +3878,7 @@ static int iwl4965_rx_agg_start(struct iwl_priv *priv,
3878 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 3878 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
3879 spin_unlock_irqrestore(&priv->sta_lock, flags); 3879 spin_unlock_irqrestore(&priv->sta_lock, flags);
3880 3880
3881 return iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, 3881 return iwl_send_add_sta(priv, &priv->stations[sta_id].sta,
3882 CMD_ASYNC); 3882 CMD_ASYNC);
3883} 3883}
3884 3884
@@ -3899,7 +3899,7 @@ static int iwl4965_rx_agg_stop(struct iwl_priv *priv,
3899 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 3899 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
3900 spin_unlock_irqrestore(&priv->sta_lock, flags); 3900 spin_unlock_irqrestore(&priv->sta_lock, flags);
3901 3901
3902 return iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, 3902 return iwl_send_add_sta(priv, &priv->stations[sta_id].sta,
3903 CMD_ASYNC); 3903 CMD_ASYNC);
3904} 3904}
3905 3905
@@ -4064,9 +4064,26 @@ int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw,
4064 } 4064 }
4065 return 0; 4065 return 0;
4066} 4066}
4067
4068#endif /* CONFIG_IWL4965_HT */ 4067#endif /* CONFIG_IWL4965_HT */
4069 4068
4069
4070static u16 iwl4965_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
4071{
4072 struct iwl4965_addsta_cmd *addsta = (struct iwl4965_addsta_cmd *)data;
4073 addsta->mode = cmd->mode;
4074 memcpy(&addsta->sta, &cmd->sta, sizeof(struct sta_id_modify));
4075 memcpy(&addsta->key, &cmd->key, sizeof(struct iwl4965_keyinfo));
4076 addsta->station_flags = cmd->station_flags;
4077 addsta->station_flags_msk = cmd->station_flags_msk;
4078 addsta->tid_disable_tx = cmd->tid_disable_tx;
4079 addsta->add_immediate_ba_tid = cmd->add_immediate_ba_tid;
4080 addsta->remove_immediate_ba_tid = cmd->remove_immediate_ba_tid;
4081 addsta->add_immediate_ba_ssn = cmd->add_immediate_ba_ssn;
4082 addsta->reserved1 = __constant_cpu_to_le16(0);
4083 addsta->reserved2 = __constant_cpu_to_le32(0);
4084
4085 return (u16)sizeof(struct iwl4965_addsta_cmd);
4086}
4070/* Set up 4965-specific Rx frame reply handlers */ 4087/* Set up 4965-specific Rx frame reply handlers */
4071static void iwl4965_rx_handler_setup(struct iwl_priv *priv) 4088static void iwl4965_rx_handler_setup(struct iwl_priv *priv)
4072{ 4089{
@@ -4110,6 +4127,7 @@ static struct iwl_hcmd_ops iwl4965_hcmd = {
4110 4127
4111static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = { 4128static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
4112 .enqueue_hcmd = iwl4965_enqueue_hcmd, 4129 .enqueue_hcmd = iwl4965_enqueue_hcmd,
4130 .build_addsta_hcmd = iwl4965_build_addsta_hcmd,
4113#ifdef CONFIG_IWL4965_RUN_TIME_CALIB 4131#ifdef CONFIG_IWL4965_RUN_TIME_CALIB
4114 .chain_noise_reset = iwl4965_chain_noise_reset, 4132 .chain_noise_reset = iwl4965_chain_noise_reset,
4115 .gain_computation = iwl4965_gain_computation, 4133 .gain_computation = iwl4965_gain_computation,
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index e5449b8c3359..d16a853f376a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -769,6 +769,20 @@ struct iwl4965_keyinfo {
769 u8 key[16]; /* 16-byte unicast decryption key */ 769 u8 key[16]; /* 16-byte unicast decryption key */
770} __attribute__ ((packed)); 770} __attribute__ ((packed));
771 771
772/* 5000 */
773struct iwl_keyinfo {
774 __le16 key_flags;
775 u8 tkip_rx_tsc_byte2; /* TSC[2] for key mix ph1 detection */
776 u8 reserved1;
777 __le16 tkip_rx_ttak[5]; /* 10-byte unicast TKIP TTAK */
778 u8 key_offset;
779 u8 reserved2;
780 u8 key[16]; /* 16-byte unicast decryption key */
781 __le64 tx_secur_seq_cnt;
782 __le64 hw_tkip_mic_rx_key;
783 __le64 hw_tkip_mic_tx_key;
784} __attribute__ ((packed));
785
772/** 786/**
773 * struct sta_id_modify 787 * struct sta_id_modify
774 * @addr[ETH_ALEN]: station's MAC address 788 * @addr[ETH_ALEN]: station's MAC address
@@ -844,6 +858,38 @@ struct iwl4965_addsta_cmd {
844 __le32 reserved2; 858 __le32 reserved2;
845} __attribute__ ((packed)); 859} __attribute__ ((packed));
846 860
861/* 5000 */
862struct iwl_addsta_cmd {
863 u8 mode; /* 1: modify existing, 0: add new station */
864 u8 reserved[3];
865 struct sta_id_modify sta;
866 struct iwl_keyinfo key;
867 __le32 station_flags; /* STA_FLG_* */
868 __le32 station_flags_msk; /* STA_FLG_* */
869
870 /* bit field to disable (1) or enable (0) Tx for Traffic ID (TID)
871 * corresponding to bit (e.g. bit 5 controls TID 5).
872 * Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */
873 __le16 tid_disable_tx;
874
875 __le16 reserved1;
876
877 /* TID for which to add block-ack support.
878 * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
879 u8 add_immediate_ba_tid;
880
881 /* TID for which to remove block-ack support.
882 * Set modify_mask bit STA_MODIFY_DELBA_TID_MSK to use this field. */
883 u8 remove_immediate_ba_tid;
884
885 /* Starting Sequence Number for added block-ack support.
886 * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
887 __le16 add_immediate_ba_ssn;
888
889 __le32 reserved2;
890} __attribute__ ((packed));
891
892
847#define ADD_STA_SUCCESS_MSK 0x1 893#define ADD_STA_SUCCESS_MSK 0x1
848#define ADD_STA_NO_ROOM_IN_TABLE 0x2 894#define ADD_STA_NO_ROOM_IN_TABLE 0x2
849#define ADD_STA_NO_BLOCK_ACK_RESOURCE 0x4 895#define ADD_STA_NO_BLOCK_ACK_RESOURCE 0x4
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 2356cadc1def..df27ee65015c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -87,6 +87,7 @@ struct iwl_hcmd_ops {
87}; 87};
88struct iwl_hcmd_utils_ops { 88struct iwl_hcmd_utils_ops {
89 int (*enqueue_hcmd)(struct iwl_priv *priv, struct iwl_host_cmd *cmd); 89 int (*enqueue_hcmd)(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
90 u16 (*build_addsta_hcmd)(const struct iwl_addsta_cmd *cmd, u8 *data);
90#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB 91#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB
91 void (*gain_computation)(struct iwl_priv *priv, 92 void (*gain_computation)(struct iwl_priv *priv,
92 u32 *average_noise, 93 u32 *average_noise,
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 07eff75786b4..4786194c0454 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -319,7 +319,7 @@ struct iwl_cmd {
319 struct iwl_cmd_meta meta; /* driver data */ 319 struct iwl_cmd_meta meta; /* driver data */
320 struct iwl_cmd_header hdr; /* uCode API */ 320 struct iwl_cmd_header hdr; /* uCode API */
321 union { 321 union {
322 struct iwl4965_addsta_cmd addsta; 322 struct iwl_addsta_cmd addsta;
323 struct iwl4965_led_cmd led; 323 struct iwl4965_led_cmd led;
324 u32 flags; 324 u32 flags;
325 u8 val8; 325 u8 val8;
@@ -511,7 +511,7 @@ struct iwl4965_qos_info {
511#define STA_PS_STATUS_SLEEP 1 511#define STA_PS_STATUS_SLEEP 1
512 512
513struct iwl_station_entry { 513struct iwl_station_entry {
514 struct iwl4965_addsta_cmd sta; 514 struct iwl_addsta_cmd sta;
515 struct iwl_tid_data tid[MAX_TID_COUNT]; 515 struct iwl_tid_data tid[MAX_TID_COUNT];
516 u8 used; 516 u8 used;
517 u8 ps_status; 517 u8 ps_status;
@@ -634,9 +634,9 @@ struct iwl_hw_params {
634 * for use by iwl-*.c 634 * for use by iwl-*.c
635 * 635 *
636 *****************************************************************************/ 636 *****************************************************************************/
637struct iwl4965_addsta_cmd; 637struct iwl_addsta_cmd;
638extern int iwl4965_send_add_station(struct iwl_priv *priv, 638extern int iwl_send_add_sta(struct iwl_priv *priv,
639 struct iwl4965_addsta_cmd *sta, u8 flags); 639 struct iwl_addsta_cmd *sta, u8 flags);
640extern u8 iwl4965_add_station_flags(struct iwl_priv *priv, const u8 *addr, 640extern u8 iwl4965_add_station_flags(struct iwl_priv *priv, const u8 *addr,
641 int is_ap, u8 flags, void *ht_data); 641 int is_ap, u8 flags, void *ht_data);
642extern int iwl4965_is_network_packet(struct iwl_priv *priv, 642extern int iwl4965_is_network_packet(struct iwl_priv *priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 0148d49e0b57..34f54244ed27 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -70,6 +70,52 @@ u8 iwl_find_station(struct iwl_priv *priv, const u8 *addr)
70} 70}
71EXPORT_SYMBOL(iwl_find_station); 71EXPORT_SYMBOL(iwl_find_station);
72 72
73int iwl_send_add_sta(struct iwl_priv *priv,
74 struct iwl_addsta_cmd *sta, u8 flags)
75{
76 struct iwl_rx_packet *res = NULL;
77 int ret = 0;
78 u8 data[sizeof(*sta)];
79 struct iwl_host_cmd cmd = {
80 .id = REPLY_ADD_STA,
81 .meta.flags = flags,
82 .data = data,
83 };
84
85 if (!(flags & CMD_ASYNC))
86 cmd.meta.flags |= CMD_WANT_SKB;
87
88 cmd.len = priv->cfg->ops->utils->build_addsta_hcmd(sta, data);
89 ret = iwl_send_cmd(priv, &cmd);
90
91 if (ret || (flags & CMD_ASYNC))
92 return ret;
93
94 res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
95 if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
96 IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n",
97 res->hdr.flags);
98 ret = -EIO;
99 }
100
101 if (ret == 0) {
102 switch (res->u.add_sta.status) {
103 case ADD_STA_SUCCESS_MSK:
104 IWL_DEBUG_INFO("REPLY_ADD_STA PASSED\n");
105 break;
106 default:
107 ret = -EIO;
108 IWL_WARNING("REPLY_ADD_STA failed\n");
109 break;
110 }
111 }
112
113 priv->alloc_rxb_skb--;
114 dev_kfree_skb_any(cmd.meta.u.skb);
115
116 return ret;
117}
118EXPORT_SYMBOL(iwl_send_add_sta);
73 119
74int iwl_get_free_ucode_key_index(struct iwl_priv *priv) 120int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
75{ 121{
@@ -216,8 +262,7 @@ static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv,
216 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; 262 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
217 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 263 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
218 264
219 ret = iwl4965_send_add_station(priv, 265 ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
220 &priv->stations[sta_id].sta, CMD_ASYNC);
221 266
222 spin_unlock_irqrestore(&priv->sta_lock, flags); 267 spin_unlock_irqrestore(&priv->sta_lock, flags);
223 268
@@ -265,8 +310,7 @@ static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
265 spin_unlock_irqrestore(&priv->sta_lock, flags); 310 spin_unlock_irqrestore(&priv->sta_lock, flags);
266 311
267 IWL_DEBUG_INFO("hwcrypto: modify ucode station key info\n"); 312 IWL_DEBUG_INFO("hwcrypto: modify ucode station key info\n");
268 return iwl4965_send_add_station(priv, 313 return iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
269 &priv->stations[sta_id].sta, CMD_ASYNC);
270} 314}
271 315
272static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv, 316static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv,
@@ -343,7 +387,7 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv,
343 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 387 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
344 388
345 IWL_DEBUG_INFO("hwcrypto: clear ucode station key info\n"); 389 IWL_DEBUG_INFO("hwcrypto: clear ucode station key info\n");
346 ret = iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, 0); 390 ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, 0);
347 spin_unlock_irqrestore(&priv->sta_lock, flags); 391 spin_unlock_irqrestore(&priv->sta_lock, flags);
348 return ret; 392 return ret;
349} 393}
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index 5b9cbbd197f6..8427bc9a9bbc 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -476,7 +476,7 @@ u8 iwl4965_add_station_flags(struct iwl_priv *priv, const u8 *addr,
476 priv->num_stations++; 476 priv->num_stations++;
477 477
478 /* Set up the REPLY_ADD_STA command to send to device */ 478 /* Set up the REPLY_ADD_STA command to send to device */
479 memset(&station->sta, 0, sizeof(struct iwl4965_addsta_cmd)); 479 memset(&station->sta, 0, sizeof(struct iwl_addsta_cmd));
480 memcpy(station->sta.sta.addr, addr, ETH_ALEN); 480 memcpy(station->sta.sta.addr, addr, ETH_ALEN);
481 station->sta.mode = 0; 481 station->sta.mode = 0;
482 station->sta.sta.sta_id = index; 482 station->sta.sta.sta_id = index;
@@ -493,7 +493,7 @@ u8 iwl4965_add_station_flags(struct iwl_priv *priv, const u8 *addr,
493 spin_unlock_irqrestore(&priv->sta_lock, flags_spin); 493 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
494 494
495 /* Add station to device's station table */ 495 /* Add station to device's station table */
496 iwl4965_send_add_station(priv, &station->sta, flags); 496 iwl_send_add_sta(priv, &station->sta, flags);
497 return index; 497 return index;
498 498
499} 499}
@@ -963,51 +963,6 @@ static int iwl4965_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_fla
963 return iwl_send_cmd(priv, &cmd); 963 return iwl_send_cmd(priv, &cmd);
964} 964}
965 965
966int iwl4965_send_add_station(struct iwl_priv *priv,
967 struct iwl4965_addsta_cmd *sta, u8 flags)
968{
969 struct iwl_rx_packet *res = NULL;
970 int rc = 0;
971 struct iwl_host_cmd cmd = {
972 .id = REPLY_ADD_STA,
973 .len = sizeof(struct iwl4965_addsta_cmd),
974 .meta.flags = flags,
975 .data = sta,
976 };
977
978 if (!(flags & CMD_ASYNC))
979 cmd.meta.flags |= CMD_WANT_SKB;
980
981 rc = iwl_send_cmd(priv, &cmd);
982
983 if (rc || (flags & CMD_ASYNC))
984 return rc;
985
986 res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
987 if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
988 IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n",
989 res->hdr.flags);
990 rc = -EIO;
991 }
992
993 if (rc == 0) {
994 switch (res->u.add_sta.status) {
995 case ADD_STA_SUCCESS_MSK:
996 IWL_DEBUG_INFO("REPLY_ADD_STA PASSED\n");
997 break;
998 default:
999 rc = -EIO;
1000 IWL_WARNING("REPLY_ADD_STA failed\n");
1001 break;
1002 }
1003 }
1004
1005 priv->alloc_rxb_skb--;
1006 dev_kfree_skb_any(cmd.meta.u.skb);
1007
1008 return rc;
1009}
1010
1011static void iwl4965_clear_free_frames(struct iwl_priv *priv) 966static void iwl4965_clear_free_frames(struct iwl_priv *priv)
1012{ 967{
1013 struct list_head *element; 968 struct list_head *element;
@@ -5927,7 +5882,7 @@ static void iwl4965_mac_update_tkip_key(struct ieee80211_hw *hw,
5927 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; 5882 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
5928 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 5883 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
5929 5884
5930 iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC); 5885 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
5931 5886
5932 spin_unlock_irqrestore(&priv->sta_lock, flags); 5887 spin_unlock_irqrestore(&priv->sta_lock, flags);
5933 5888