diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
19 files changed, 1008 insertions, 687 deletions
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index bcaa61b7c563..f844b738d34e 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig | |||
@@ -6,7 +6,7 @@ config IWLWIFI_LEDS | |||
6 | bool | 6 | bool |
7 | default n | 7 | default n |
8 | 8 | ||
9 | config IWLCORE_RFKILL | 9 | config IWLWIFI_RFKILL |
10 | boolean "IWLWIFI RF kill support" | 10 | boolean "IWLWIFI RF kill support" |
11 | depends on IWLCORE | 11 | depends on IWLCORE |
12 | select RFKILL | 12 | select RFKILL |
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 2751e8aa97d7..4f3e88b12e3a 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile | |||
@@ -1,26 +1,13 @@ | |||
1 | obj-$(CONFIG_IWLCORE) += iwlcore.o | 1 | obj-$(CONFIG_IWLCORE) := iwlcore.o |
2 | iwlcore-objs = iwl-core.o iwl-eeprom.o iwl-hcmd.o | 2 | iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o |
3 | 3 | iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o | |
4 | ifeq ($(CONFIG_IWLWIFI_DEBUGFS),y) | 4 | iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o |
5 | iwlcore-objs += iwl-debugfs.o | 5 | iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o |
6 | endif | ||
7 | |||
8 | ifeq ($(CONFIG_IWLWIFI_LEDS),y) | ||
9 | iwlcore-objs += iwl-led.o | ||
10 | endif | ||
11 | |||
12 | ifeq ($(CONFIG_IWLCORE_RFKILL),y) | ||
13 | iwlcore-objs += iwl-rfkill.o | ||
14 | endif | ||
15 | 6 | ||
16 | obj-$(CONFIG_IWL3945) += iwl3945.o | 7 | obj-$(CONFIG_IWL3945) += iwl3945.o |
17 | iwl3945-objs = iwl3945-base.o iwl-3945.o iwl-3945-rs.o | 8 | iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o |
18 | 9 | iwl3945-$(CONFIG_IWL3945_LEDS) += iwl-3945-led.o | |
19 | ifeq ($(CONFIG_IWL3945_LEDS),y) | ||
20 | iwl3945-objs += iwl-3945-led.o | ||
21 | endif | ||
22 | |||
23 | 10 | ||
24 | obj-$(CONFIG_IWL4965) += iwl4965.o | 11 | obj-$(CONFIG_IWL4965) += iwl4965.o |
25 | iwl4965-objs = iwl4965-base.o iwl-4965.o iwl-4965-rs.o | 12 | iwl4965-objs := iwl4965-base.o iwl-4965.o iwl-4965-rs.o iwl-sta.o |
26 | 13 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h index 368da9852aab..ad612a8719f4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h | |||
@@ -456,7 +456,7 @@ struct iwl3945_eeprom { | |||
456 | /* Size of uCode instruction memory in bootstrap state machine */ | 456 | /* Size of uCode instruction memory in bootstrap state machine */ |
457 | #define IWL_MAX_BSM_SIZE ALM_RTC_INST_SIZE | 457 | #define IWL_MAX_BSM_SIZE ALM_RTC_INST_SIZE |
458 | 458 | ||
459 | #define IWL_MAX_NUM_QUEUES 8 | 459 | #define IWL39_MAX_NUM_QUEUES 8 |
460 | 460 | ||
461 | static inline int iwl3945_hw_valid_rtc_data_addr(u32 addr) | 461 | static inline int iwl3945_hw_valid_rtc_data_addr(u32 addr) |
462 | { | 462 | { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index 3dc7f0fbf02f..45c1c5533bf0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h | |||
@@ -687,6 +687,8 @@ enum { | |||
687 | 687 | ||
688 | #endif | 688 | #endif |
689 | 689 | ||
690 | #define IWL_MAX_NUM_QUEUES IWL39_MAX_NUM_QUEUES | ||
691 | |||
690 | struct iwl3945_priv { | 692 | struct iwl3945_priv { |
691 | 693 | ||
692 | /* ieee device used by generic ieee processing code */ | 694 | /* ieee device used by generic ieee processing code */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-commands.h b/drivers/net/wireless/iwlwifi/iwl-4965-commands.h index 7e36ecb27575..3bcd107e2d71 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965-commands.h | |||
@@ -84,6 +84,9 @@ enum { | |||
84 | REPLY_REMOVE_STA = 0x19, /* not used */ | 84 | REPLY_REMOVE_STA = 0x19, /* not used */ |
85 | REPLY_REMOVE_ALL_STA = 0x1a, /* not used */ | 85 | REPLY_REMOVE_ALL_STA = 0x1a, /* not used */ |
86 | 86 | ||
87 | /* Security */ | ||
88 | REPLY_WEPKEY = 0x20, | ||
89 | |||
87 | /* RX, TX, LEDs */ | 90 | /* RX, TX, LEDs */ |
88 | REPLY_TX = 0x1c, | 91 | REPLY_TX = 0x1c, |
89 | REPLY_RATE_SCALE = 0x47, /* 3945 only */ | 92 | REPLY_RATE_SCALE = 0x47, /* 3945 only */ |
@@ -266,11 +269,10 @@ struct iwl_cmd_header { | |||
266 | * 10 B active, A inactive | 269 | * 10 B active, A inactive |
267 | * 11 Both active | 270 | * 11 Both active |
268 | */ | 271 | */ |
269 | #define RATE_MCS_ANT_A_POS 14 | 272 | #define RATE_MCS_ANT_POS 14 |
270 | #define RATE_MCS_ANT_B_POS 15 | 273 | #define RATE_MCS_ANT_A_MSK 0x04000 |
271 | #define RATE_MCS_ANT_A_MSK 0x4000 | 274 | #define RATE_MCS_ANT_B_MSK 0x08000 |
272 | #define RATE_MCS_ANT_B_MSK 0x8000 | 275 | #define RATE_MCS_ANT_AB_MSK 0x0C000 |
273 | #define RATE_MCS_ANT_AB_MSK 0xc000 | ||
274 | 276 | ||
275 | 277 | ||
276 | /** | 278 | /** |
@@ -850,6 +852,30 @@ struct iwl4965_add_sta_resp { | |||
850 | u8 status; /* ADD_STA_* */ | 852 | u8 status; /* ADD_STA_* */ |
851 | } __attribute__ ((packed)); | 853 | } __attribute__ ((packed)); |
852 | 854 | ||
855 | /* | ||
856 | * REPLY_WEP_KEY = 0x20 | ||
857 | */ | ||
858 | struct iwl_wep_key { | ||
859 | u8 key_index; | ||
860 | u8 key_offset; | ||
861 | u8 reserved1[2]; | ||
862 | u8 key_size; | ||
863 | u8 reserved2[3]; | ||
864 | u8 key[16]; | ||
865 | } __attribute__ ((packed)); | ||
866 | |||
867 | struct iwl_wep_cmd { | ||
868 | u8 num_keys; | ||
869 | u8 global_key_type; | ||
870 | u8 flags; | ||
871 | u8 reserved; | ||
872 | struct iwl_wep_key key[0]; | ||
873 | } __attribute__ ((packed)); | ||
874 | |||
875 | #define WEP_KEY_WEP_TYPE 1 | ||
876 | #define WEP_KEYS_MAX 4 | ||
877 | #define WEP_INVALID_OFFSET 0xff | ||
878 | #define WEP_KEY_LEN_128 13 | ||
853 | 879 | ||
854 | /****************************************************************************** | 880 | /****************************************************************************** |
855 | * (4) | 881 | * (4) |
@@ -1387,11 +1413,11 @@ struct iwl4965_txpowertable_cmd { | |||
1387 | 1413 | ||
1388 | 1414 | ||
1389 | /** | 1415 | /** |
1390 | * struct iwl4965_link_qual_general_params | 1416 | * struct iwl_link_qual_general_params |
1391 | * | 1417 | * |
1392 | * Used in REPLY_TX_LINK_QUALITY_CMD | 1418 | * Used in REPLY_TX_LINK_QUALITY_CMD |
1393 | */ | 1419 | */ |
1394 | struct iwl4965_link_qual_general_params { | 1420 | struct iwl_link_qual_general_params { |
1395 | u8 flags; | 1421 | u8 flags; |
1396 | 1422 | ||
1397 | /* No entries at or above this (driver chosen) index contain MIMO */ | 1423 | /* No entries at or above this (driver chosen) index contain MIMO */ |
@@ -1418,11 +1444,11 @@ struct iwl4965_link_qual_general_params { | |||
1418 | } __attribute__ ((packed)); | 1444 | } __attribute__ ((packed)); |
1419 | 1445 | ||
1420 | /** | 1446 | /** |
1421 | * struct iwl4965_link_qual_agg_params | 1447 | * struct iwl_link_qual_agg_params |
1422 | * | 1448 | * |
1423 | * Used in REPLY_TX_LINK_QUALITY_CMD | 1449 | * Used in REPLY_TX_LINK_QUALITY_CMD |
1424 | */ | 1450 | */ |
1425 | struct iwl4965_link_qual_agg_params { | 1451 | struct iwl_link_qual_agg_params { |
1426 | 1452 | ||
1427 | /* Maximum number of uSec in aggregation. | 1453 | /* Maximum number of uSec in aggregation. |
1428 | * Driver should set this to 4000 (4 milliseconds). */ | 1454 | * Driver should set this to 4000 (4 milliseconds). */ |
@@ -1632,14 +1658,14 @@ struct iwl4965_link_qual_agg_params { | |||
1632 | * legacy), and then repeat the search process. | 1658 | * legacy), and then repeat the search process. |
1633 | * | 1659 | * |
1634 | */ | 1660 | */ |
1635 | struct iwl4965_link_quality_cmd { | 1661 | struct iwl_link_quality_cmd { |
1636 | 1662 | ||
1637 | /* Index of destination/recipient station in uCode's station table */ | 1663 | /* Index of destination/recipient station in uCode's station table */ |
1638 | u8 sta_id; | 1664 | u8 sta_id; |
1639 | u8 reserved1; | 1665 | u8 reserved1; |
1640 | __le16 control; /* not used */ | 1666 | __le16 control; /* not used */ |
1641 | struct iwl4965_link_qual_general_params general_params; | 1667 | struct iwl_link_qual_general_params general_params; |
1642 | struct iwl4965_link_qual_agg_params agg_params; | 1668 | struct iwl_link_qual_agg_params agg_params; |
1643 | 1669 | ||
1644 | /* | 1670 | /* |
1645 | * Rate info; when using rate-scaling, Tx command's initial_rate_index | 1671 | * Rate info; when using rate-scaling, Tx command's initial_rate_index |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h index de7bac149723..1a66b508a8ea 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h | |||
@@ -1385,10 +1385,10 @@ static inline __le32 iwl4965_hw_set_rate_n_flags(u8 rate, u16 flags) | |||
1385 | * up to 7 DMA channels (FIFOs). Each Tx queue is supported by a circular array | 1385 | * up to 7 DMA channels (FIFOs). Each Tx queue is supported by a circular array |
1386 | * in DRAM containing 256 Transmit Frame Descriptors (TFDs). | 1386 | * in DRAM containing 256 Transmit Frame Descriptors (TFDs). |
1387 | */ | 1387 | */ |
1388 | #define IWL4965_MAX_WIN_SIZE 64 | 1388 | #define IWL4965_MAX_WIN_SIZE 64 |
1389 | #define IWL4965_QUEUE_SIZE 256 | 1389 | #define IWL4965_QUEUE_SIZE 256 |
1390 | #define IWL4965_NUM_FIFOS 7 | 1390 | #define IWL4965_NUM_FIFOS 7 |
1391 | #define IWL_MAX_NUM_QUEUES 16 | 1391 | #define IWL4965_MAX_NUM_QUEUES 16 |
1392 | 1392 | ||
1393 | 1393 | ||
1394 | /** | 1394 | /** |
@@ -1553,30 +1553,30 @@ struct iwl4965_sched_queue_byte_cnt_tbl { | |||
1553 | */ | 1553 | */ |
1554 | struct iwl4965_shared { | 1554 | struct iwl4965_shared { |
1555 | struct iwl4965_sched_queue_byte_cnt_tbl | 1555 | struct iwl4965_sched_queue_byte_cnt_tbl |
1556 | queues_byte_cnt_tbls[IWL_MAX_NUM_QUEUES]; | 1556 | queues_byte_cnt_tbls[IWL4965_MAX_NUM_QUEUES]; |
1557 | __le32 val0; | 1557 | __le32 rb_closed; |
1558 | 1558 | ||
1559 | /* __le32 rb_closed_stts_rb_num:12; */ | 1559 | /* __le32 rb_closed_stts_rb_num:12; */ |
1560 | #define IWL_rb_closed_stts_rb_num_POS 0 | 1560 | #define IWL_rb_closed_stts_rb_num_POS 0 |
1561 | #define IWL_rb_closed_stts_rb_num_LEN 12 | 1561 | #define IWL_rb_closed_stts_rb_num_LEN 12 |
1562 | #define IWL_rb_closed_stts_rb_num_SYM val0 | 1562 | #define IWL_rb_closed_stts_rb_num_SYM rb_closed |
1563 | /* __le32 rsrv1:4; */ | 1563 | /* __le32 rsrv1:4; */ |
1564 | /* __le32 rb_closed_stts_rx_frame_num:12; */ | 1564 | /* __le32 rb_closed_stts_rx_frame_num:12; */ |
1565 | #define IWL_rb_closed_stts_rx_frame_num_POS 16 | 1565 | #define IWL_rb_closed_stts_rx_frame_num_POS 16 |
1566 | #define IWL_rb_closed_stts_rx_frame_num_LEN 12 | 1566 | #define IWL_rb_closed_stts_rx_frame_num_LEN 12 |
1567 | #define IWL_rb_closed_stts_rx_frame_num_SYM val0 | 1567 | #define IWL_rb_closed_stts_rx_frame_num_SYM rb_closed |
1568 | /* __le32 rsrv2:4; */ | 1568 | /* __le32 rsrv2:4; */ |
1569 | 1569 | ||
1570 | __le32 val1; | 1570 | __le32 frm_finished; |
1571 | /* __le32 frame_finished_stts_rb_num:12; */ | 1571 | /* __le32 frame_finished_stts_rb_num:12; */ |
1572 | #define IWL_frame_finished_stts_rb_num_POS 0 | 1572 | #define IWL_frame_finished_stts_rb_num_POS 0 |
1573 | #define IWL_frame_finished_stts_rb_num_LEN 12 | 1573 | #define IWL_frame_finished_stts_rb_num_LEN 12 |
1574 | #define IWL_frame_finished_stts_rb_num_SYM val1 | 1574 | #define IWL_frame_finished_stts_rb_num_SYM frm_finished |
1575 | /* __le32 rsrv3:4; */ | 1575 | /* __le32 rsrv3:4; */ |
1576 | /* __le32 frame_finished_stts_rx_frame_num:12; */ | 1576 | /* __le32 frame_finished_stts_rx_frame_num:12; */ |
1577 | #define IWL_frame_finished_stts_rx_frame_num_POS 16 | 1577 | #define IWL_frame_finished_stts_rx_frame_num_POS 16 |
1578 | #define IWL_frame_finished_stts_rx_frame_num_LEN 12 | 1578 | #define IWL_frame_finished_stts_rx_frame_num_LEN 12 |
1579 | #define IWL_frame_finished_stts_rx_frame_num_SYM val1 | 1579 | #define IWL_frame_finished_stts_rx_frame_num_SYM frm_finished |
1580 | /* __le32 rsrv4:4; */ | 1580 | /* __le32 rsrv4:4; */ |
1581 | 1581 | ||
1582 | __le32 padding1; /* so that allocation will be aligned to 16B */ | 1582 | __le32 padding1; /* so that allocation will be aligned to 16B */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c index 315b0433801e..b608e1ca8b40 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c | |||
@@ -150,7 +150,7 @@ struct iwl4965_lq_sta { | |||
150 | u16 active_mimo_rate; | 150 | u16 active_mimo_rate; |
151 | u16 active_rate_basic; | 151 | u16 active_rate_basic; |
152 | 152 | ||
153 | struct iwl4965_link_quality_cmd lq; | 153 | struct iwl_link_quality_cmd lq; |
154 | struct iwl4965_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */ | 154 | struct iwl4965_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */ |
155 | #ifdef CONFIG_IWL4965_HT | 155 | #ifdef CONFIG_IWL4965_HT |
156 | struct iwl4965_traffic_load load[TID_MAX_LOAD_COUNT]; | 156 | struct iwl4965_traffic_load load[TID_MAX_LOAD_COUNT]; |
@@ -173,7 +173,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
173 | struct sta_info *sta); | 173 | struct sta_info *sta); |
174 | static void rs_fill_link_cmd(struct iwl4965_lq_sta *lq_sta, | 174 | static void rs_fill_link_cmd(struct iwl4965_lq_sta *lq_sta, |
175 | struct iwl4965_rate *tx_mcs, | 175 | struct iwl4965_rate *tx_mcs, |
176 | struct iwl4965_link_quality_cmd *tbl); | 176 | struct iwl_link_quality_cmd *tbl); |
177 | 177 | ||
178 | 178 | ||
179 | #ifdef CONFIG_MAC80211_DEBUGFS | 179 | #ifdef CONFIG_MAC80211_DEBUGFS |
@@ -230,58 +230,11 @@ static s32 expected_tpt_mimo40MHzSGI[IWL_RATE_COUNT] = { | |||
230 | 0, 0, 0, 0, 131, 131, 191, 222, 242, 270, 284, 289, 293 | 230 | 0, 0, 0, 0, 131, 131, 191, 222, 242, 270, 284, 289, 293 |
231 | }; | 231 | }; |
232 | 232 | ||
233 | static int iwl4965_lq_sync_callback(struct iwl_priv *priv, | ||
234 | struct iwl_cmd *cmd, struct sk_buff *skb) | ||
235 | { | ||
236 | /*We didn't cache the SKB; let the caller free it */ | ||
237 | return 1; | ||
238 | } | ||
239 | |||
240 | static inline u8 iwl4965_rate_get_rate(u32 rate_n_flags) | 233 | static inline u8 iwl4965_rate_get_rate(u32 rate_n_flags) |
241 | { | 234 | { |
242 | return (u8)(rate_n_flags & 0xFF); | 235 | return (u8)(rate_n_flags & 0xFF); |
243 | } | 236 | } |
244 | 237 | ||
245 | static int rs_send_lq_cmd(struct iwl_priv *priv, | ||
246 | struct iwl4965_link_quality_cmd *lq, u8 flags) | ||
247 | { | ||
248 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
249 | int i; | ||
250 | #endif | ||
251 | struct iwl_host_cmd cmd = { | ||
252 | .id = REPLY_TX_LINK_QUALITY_CMD, | ||
253 | .len = sizeof(struct iwl4965_link_quality_cmd), | ||
254 | .meta.flags = flags, | ||
255 | .data = lq, | ||
256 | }; | ||
257 | |||
258 | if ((lq->sta_id == 0xFF) && | ||
259 | (priv->iw_mode == IEEE80211_IF_TYPE_IBSS)) | ||
260 | return -EINVAL; | ||
261 | |||
262 | if (lq->sta_id == 0xFF) | ||
263 | lq->sta_id = IWL_AP_ID; | ||
264 | |||
265 | IWL_DEBUG_RATE("lq station id 0x%x\n", lq->sta_id); | ||
266 | IWL_DEBUG_RATE("lq dta 0x%X 0x%X\n", | ||
267 | lq->general_params.single_stream_ant_msk, | ||
268 | lq->general_params.dual_stream_ant_msk); | ||
269 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
270 | for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) | ||
271 | IWL_DEBUG_RATE("lq index %d 0x%X\n", | ||
272 | i, lq->rs_table[i].rate_n_flags); | ||
273 | #endif | ||
274 | |||
275 | if (flags & CMD_ASYNC) | ||
276 | cmd.meta.u.callback = iwl4965_lq_sync_callback; | ||
277 | |||
278 | if (iwl_is_associated(priv) && priv->assoc_station_added && | ||
279 | priv->lq_mngr.lq_ready) | ||
280 | return iwl_send_cmd(priv, &cmd); | ||
281 | |||
282 | return 0; | ||
283 | } | ||
284 | |||
285 | static void rs_rate_scale_clear_window(struct iwl4965_rate_scale_data *window) | 238 | static void rs_rate_scale_clear_window(struct iwl4965_rate_scale_data *window) |
286 | { | 239 | { |
287 | window->data = 0; | 240 | window->data = 0; |
@@ -819,7 +772,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
819 | u8 retries; | 772 | u8 retries; |
820 | int rs_index, index = 0; | 773 | int rs_index, index = 0; |
821 | struct iwl4965_lq_sta *lq_sta; | 774 | struct iwl4965_lq_sta *lq_sta; |
822 | struct iwl4965_link_quality_cmd *table; | 775 | struct iwl_link_quality_cmd *table; |
823 | struct sta_info *sta; | 776 | struct sta_info *sta; |
824 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 777 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
825 | struct iwl_priv *priv = (struct iwl_priv *)priv_rate; | 778 | struct iwl_priv *priv = (struct iwl_priv *)priv_rate; |
@@ -1879,7 +1832,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
1879 | if (update_lq) { | 1832 | if (update_lq) { |
1880 | rs_mcs_from_tbl(&mcs_rate, tbl, index, is_green); | 1833 | rs_mcs_from_tbl(&mcs_rate, tbl, index, is_green); |
1881 | rs_fill_link_cmd(lq_sta, &mcs_rate, &lq_sta->lq); | 1834 | rs_fill_link_cmd(lq_sta, &mcs_rate, &lq_sta->lq); |
1882 | rs_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); | 1835 | iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); |
1883 | } | 1836 | } |
1884 | goto out; | 1837 | goto out; |
1885 | 1838 | ||
@@ -2044,7 +1997,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
2044 | if (update_lq) { | 1997 | if (update_lq) { |
2045 | rs_mcs_from_tbl(&mcs_rate, tbl, index, is_green); | 1998 | rs_mcs_from_tbl(&mcs_rate, tbl, index, is_green); |
2046 | rs_fill_link_cmd(lq_sta, &mcs_rate, &lq_sta->lq); | 1999 | rs_fill_link_cmd(lq_sta, &mcs_rate, &lq_sta->lq); |
2047 | rs_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); | 2000 | iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); |
2048 | } | 2001 | } |
2049 | 2002 | ||
2050 | /* Should we stay with this modulation mode, or search for a new one? */ | 2003 | /* Should we stay with this modulation mode, or search for a new one? */ |
@@ -2084,7 +2037,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
2084 | tbl->current_rate.rate_n_flags, index); | 2037 | tbl->current_rate.rate_n_flags, index); |
2085 | rs_fill_link_cmd(lq_sta, &tbl->current_rate, | 2038 | rs_fill_link_cmd(lq_sta, &tbl->current_rate, |
2086 | &lq_sta->lq); | 2039 | &lq_sta->lq); |
2087 | rs_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); | 2040 | iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); |
2088 | } | 2041 | } |
2089 | 2042 | ||
2090 | /* If the "active" (non-search) mode was legacy, | 2043 | /* If the "active" (non-search) mode was legacy, |
@@ -2197,7 +2150,7 @@ static void rs_initialize_lq(struct iwl_priv *priv, | |||
2197 | tbl->current_rate.rate_n_flags = mcs_rate.rate_n_flags; | 2150 | tbl->current_rate.rate_n_flags = mcs_rate.rate_n_flags; |
2198 | rs_get_expected_tpt_table(lq_sta, tbl); | 2151 | rs_get_expected_tpt_table(lq_sta, tbl); |
2199 | rs_fill_link_cmd(lq_sta, &mcs_rate, &lq_sta->lq); | 2152 | rs_fill_link_cmd(lq_sta, &mcs_rate, &lq_sta->lq); |
2200 | rs_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); | 2153 | iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); |
2201 | out: | 2154 | out: |
2202 | return; | 2155 | return; |
2203 | } | 2156 | } |
@@ -2392,7 +2345,7 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, | |||
2392 | 2345 | ||
2393 | static void rs_fill_link_cmd(struct iwl4965_lq_sta *lq_sta, | 2346 | static void rs_fill_link_cmd(struct iwl4965_lq_sta *lq_sta, |
2394 | struct iwl4965_rate *tx_mcs, | 2347 | struct iwl4965_rate *tx_mcs, |
2395 | struct iwl4965_link_quality_cmd *lq_cmd) | 2348 | struct iwl_link_quality_cmd *lq_cmd) |
2396 | { | 2349 | { |
2397 | int index = 0; | 2350 | int index = 0; |
2398 | int rate_idx; | 2351 | int rate_idx; |
@@ -2591,7 +2544,7 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file, | |||
2591 | 2544 | ||
2592 | if (lq_sta->dbg_fixed.rate_n_flags) { | 2545 | if (lq_sta->dbg_fixed.rate_n_flags) { |
2593 | rs_fill_link_cmd(lq_sta, &lq_sta->dbg_fixed, &lq_sta->lq); | 2546 | rs_fill_link_cmd(lq_sta, &lq_sta->dbg_fixed, &lq_sta->lq); |
2594 | rs_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC); | 2547 | iwl_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC); |
2595 | } | 2548 | } |
2596 | 2549 | ||
2597 | return count; | 2550 | return count; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 472ca3d7e034..17f629fb96ff 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -46,7 +46,7 @@ | |||
46 | 46 | ||
47 | /* module parameters */ | 47 | /* module parameters */ |
48 | static struct iwl_mod_params iwl4965_mod_params = { | 48 | static struct iwl_mod_params iwl4965_mod_params = { |
49 | .num_of_queues = IWL_MAX_NUM_QUEUES, | 49 | .num_of_queues = IWL4965_MAX_NUM_QUEUES, |
50 | .enable_qos = 1, | 50 | .enable_qos = 1, |
51 | .amsdu_size_8K = 1, | 51 | .amsdu_size_8K = 1, |
52 | /* the rest are 0 by default */ | 52 | /* the rest are 0 by default */ |
@@ -114,6 +114,151 @@ static const u16 default_tid_to_tx_fifo[] = { | |||
114 | 114 | ||
115 | #endif /*CONFIG_IWL4965_HT */ | 115 | #endif /*CONFIG_IWL4965_HT */ |
116 | 116 | ||
117 | /* check contents of special bootstrap uCode SRAM */ | ||
118 | static int iwl4965_verify_bsm(struct iwl_priv *priv) | ||
119 | { | ||
120 | __le32 *image = priv->ucode_boot.v_addr; | ||
121 | u32 len = priv->ucode_boot.len; | ||
122 | u32 reg; | ||
123 | u32 val; | ||
124 | |||
125 | IWL_DEBUG_INFO("Begin verify bsm\n"); | ||
126 | |||
127 | /* verify BSM SRAM contents */ | ||
128 | val = iwl_read_prph(priv, BSM_WR_DWCOUNT_REG); | ||
129 | for (reg = BSM_SRAM_LOWER_BOUND; | ||
130 | reg < BSM_SRAM_LOWER_BOUND + len; | ||
131 | reg += sizeof(u32), image++) { | ||
132 | val = iwl_read_prph(priv, reg); | ||
133 | if (val != le32_to_cpu(*image)) { | ||
134 | IWL_ERROR("BSM uCode verification failed at " | ||
135 | "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n", | ||
136 | BSM_SRAM_LOWER_BOUND, | ||
137 | reg - BSM_SRAM_LOWER_BOUND, len, | ||
138 | val, le32_to_cpu(*image)); | ||
139 | return -EIO; | ||
140 | } | ||
141 | } | ||
142 | |||
143 | IWL_DEBUG_INFO("BSM bootstrap uCode image OK\n"); | ||
144 | |||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | /** | ||
149 | * iwl4965_load_bsm - Load bootstrap instructions | ||
150 | * | ||
151 | * BSM operation: | ||
152 | * | ||
153 | * The Bootstrap State Machine (BSM) stores a short bootstrap uCode program | ||
154 | * in special SRAM that does not power down during RFKILL. When powering back | ||
155 | * up after power-saving sleeps (or during initial uCode load), the BSM loads | ||
156 | * the bootstrap program into the on-board processor, and starts it. | ||
157 | * | ||
158 | * The bootstrap program loads (via DMA) instructions and data for a new | ||
159 | * program from host DRAM locations indicated by the host driver in the | ||
160 | * BSM_DRAM_* registers. Once the new program is loaded, it starts | ||
161 | * automatically. | ||
162 | * | ||
163 | * When initializing the NIC, the host driver points the BSM to the | ||
164 | * "initialize" uCode image. This uCode sets up some internal data, then | ||
165 | * notifies host via "initialize alive" that it is complete. | ||
166 | * | ||
167 | * The host then replaces the BSM_DRAM_* pointer values to point to the | ||
168 | * normal runtime uCode instructions and a backup uCode data cache buffer | ||
169 | * (filled initially with starting data values for the on-board processor), | ||
170 | * then triggers the "initialize" uCode to load and launch the runtime uCode, | ||
171 | * which begins normal operation. | ||
172 | * | ||
173 | * When doing a power-save shutdown, runtime uCode saves data SRAM into | ||
174 | * the backup data cache in DRAM before SRAM is powered down. | ||
175 | * | ||
176 | * When powering back up, the BSM loads the bootstrap program. This reloads | ||
177 | * the runtime uCode instructions and the backup data cache into SRAM, | ||
178 | * and re-launches the runtime uCode from where it left off. | ||
179 | */ | ||
180 | static int iwl4965_load_bsm(struct iwl_priv *priv) | ||
181 | { | ||
182 | __le32 *image = priv->ucode_boot.v_addr; | ||
183 | u32 len = priv->ucode_boot.len; | ||
184 | dma_addr_t pinst; | ||
185 | dma_addr_t pdata; | ||
186 | u32 inst_len; | ||
187 | u32 data_len; | ||
188 | int i; | ||
189 | u32 done; | ||
190 | u32 reg_offset; | ||
191 | int ret; | ||
192 | |||
193 | IWL_DEBUG_INFO("Begin load bsm\n"); | ||
194 | |||
195 | /* make sure bootstrap program is no larger than BSM's SRAM size */ | ||
196 | if (len > IWL_MAX_BSM_SIZE) | ||
197 | return -EINVAL; | ||
198 | |||
199 | /* Tell bootstrap uCode where to find the "Initialize" uCode | ||
200 | * in host DRAM ... host DRAM physical address bits 35:4 for 4965. | ||
201 | * NOTE: iwl4965_initialize_alive_start() will replace these values, | ||
202 | * after the "initialize" uCode has run, to point to | ||
203 | * runtime/protocol instructions and backup data cache. */ | ||
204 | pinst = priv->ucode_init.p_addr >> 4; | ||
205 | pdata = priv->ucode_init_data.p_addr >> 4; | ||
206 | inst_len = priv->ucode_init.len; | ||
207 | data_len = priv->ucode_init_data.len; | ||
208 | |||
209 | ret = iwl_grab_nic_access(priv); | ||
210 | if (ret) | ||
211 | return ret; | ||
212 | |||
213 | iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); | ||
214 | iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); | ||
215 | iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len); | ||
216 | iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len); | ||
217 | |||
218 | /* Fill BSM memory with bootstrap instructions */ | ||
219 | for (reg_offset = BSM_SRAM_LOWER_BOUND; | ||
220 | reg_offset < BSM_SRAM_LOWER_BOUND + len; | ||
221 | reg_offset += sizeof(u32), image++) | ||
222 | _iwl_write_prph(priv, reg_offset, le32_to_cpu(*image)); | ||
223 | |||
224 | ret = iwl4965_verify_bsm(priv); | ||
225 | if (ret) { | ||
226 | iwl_release_nic_access(priv); | ||
227 | return ret; | ||
228 | } | ||
229 | |||
230 | /* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */ | ||
231 | iwl_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0); | ||
232 | iwl_write_prph(priv, BSM_WR_MEM_DST_REG, RTC_INST_LOWER_BOUND); | ||
233 | iwl_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32)); | ||
234 | |||
235 | /* Load bootstrap code into instruction SRAM now, | ||
236 | * to prepare to load "initialize" uCode */ | ||
237 | iwl_write_prph(priv, BSM_WR_CTRL_REG, BSM_WR_CTRL_REG_BIT_START); | ||
238 | |||
239 | /* Wait for load of bootstrap uCode to finish */ | ||
240 | for (i = 0; i < 100; i++) { | ||
241 | done = iwl_read_prph(priv, BSM_WR_CTRL_REG); | ||
242 | if (!(done & BSM_WR_CTRL_REG_BIT_START)) | ||
243 | break; | ||
244 | udelay(10); | ||
245 | } | ||
246 | if (i < 100) | ||
247 | IWL_DEBUG_INFO("BSM write complete, poll %d iterations\n", i); | ||
248 | else { | ||
249 | IWL_ERROR("BSM write did not complete!\n"); | ||
250 | return -EIO; | ||
251 | } | ||
252 | |||
253 | /* Enable future boot loads whenever power management unit triggers it | ||
254 | * (e.g. when powering back up after power-save shutdown) */ | ||
255 | iwl_write_prph(priv, BSM_WR_CTRL_REG, BSM_WR_CTRL_REG_BIT_START_EN); | ||
256 | |||
257 | iwl_release_nic_access(priv); | ||
258 | |||
259 | return 0; | ||
260 | } | ||
261 | |||
117 | static int iwl4965_init_drv(struct iwl_priv *priv) | 262 | static int iwl4965_init_drv(struct iwl_priv *priv) |
118 | { | 263 | { |
119 | int ret; | 264 | int ret; |
@@ -129,6 +274,18 @@ static int iwl4965_init_drv(struct iwl_priv *priv) | |||
129 | spin_lock_init(&priv->hcmd_lock); | 274 | spin_lock_init(&priv->hcmd_lock); |
130 | spin_lock_init(&priv->lq_mngr.lock); | 275 | spin_lock_init(&priv->lq_mngr.lock); |
131 | 276 | ||
277 | priv->shared_virt = pci_alloc_consistent(priv->pci_dev, | ||
278 | sizeof(struct iwl4965_shared), | ||
279 | &priv->shared_phys); | ||
280 | |||
281 | if (!priv->shared_virt) { | ||
282 | ret = -ENOMEM; | ||
283 | goto err; | ||
284 | } | ||
285 | |||
286 | memset(priv->shared_virt, 0, sizeof(struct iwl4965_shared)); | ||
287 | |||
288 | |||
132 | for (i = 0; i < IWL_IBSS_MAC_HASH_SIZE; i++) | 289 | for (i = 0; i < IWL_IBSS_MAC_HASH_SIZE; i++) |
133 | INIT_LIST_HEAD(&priv->ibss_mac_hash[i]); | 290 | INIT_LIST_HEAD(&priv->ibss_mac_hash[i]); |
134 | 291 | ||
@@ -253,7 +410,7 @@ void iwl4965_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags, | |||
253 | int rate_index; | 410 | int rate_index; |
254 | 411 | ||
255 | control->antenna_sel_tx = | 412 | control->antenna_sel_tx = |
256 | ((rate_n_flags & RATE_MCS_ANT_AB_MSK) >> RATE_MCS_ANT_A_POS); | 413 | ((rate_n_flags & RATE_MCS_ANT_AB_MSK) >> RATE_MCS_ANT_POS); |
257 | if (rate_n_flags & RATE_MCS_HT_MSK) | 414 | if (rate_n_flags & RATE_MCS_HT_MSK) |
258 | control->flags |= IEEE80211_TXCTL_OFDM_HT; | 415 | control->flags |= IEEE80211_TXCTL_OFDM_HT; |
259 | if (rate_n_flags & RATE_MCS_GF_MSK) | 416 | if (rate_n_flags & RATE_MCS_GF_MSK) |
@@ -347,10 +504,10 @@ u8 iwl4965_hw_find_station(struct iwl_priv *priv, const u8 *addr) | |||
347 | start = IWL_STA_ID; | 504 | start = IWL_STA_ID; |
348 | 505 | ||
349 | if (is_broadcast_ether_addr(addr)) | 506 | if (is_broadcast_ether_addr(addr)) |
350 | return priv->hw_setting.bcast_sta_id; | 507 | return priv->hw_params.bcast_sta_id; |
351 | 508 | ||
352 | spin_lock_irqsave(&priv->sta_lock, flags); | 509 | spin_lock_irqsave(&priv->sta_lock, flags); |
353 | for (i = start; i < priv->hw_setting.max_stations; i++) | 510 | for (i = start; i < priv->hw_params.max_stations; i++) |
354 | if ((priv->stations[i].used) && | 511 | if ((priv->stations[i].used) && |
355 | (!compare_ether_addr | 512 | (!compare_ether_addr |
356 | (priv->stations[i].sta.sta.addr, addr))) { | 513 | (priv->stations[i].sta.sta.addr, addr))) { |
@@ -401,15 +558,15 @@ static int iwl4965_nic_set_pwr_src(struct iwl_priv *priv, int pwr_max) | |||
401 | 558 | ||
402 | static int iwl4965_rx_init(struct iwl_priv *priv, struct iwl4965_rx_queue *rxq) | 559 | static int iwl4965_rx_init(struct iwl_priv *priv, struct iwl4965_rx_queue *rxq) |
403 | { | 560 | { |
404 | int rc; | 561 | int ret; |
405 | unsigned long flags; | 562 | unsigned long flags; |
406 | unsigned int rb_size; | 563 | unsigned int rb_size; |
407 | 564 | ||
408 | spin_lock_irqsave(&priv->lock, flags); | 565 | spin_lock_irqsave(&priv->lock, flags); |
409 | rc = iwl_grab_nic_access(priv); | 566 | ret = iwl_grab_nic_access(priv); |
410 | if (rc) { | 567 | if (ret) { |
411 | spin_unlock_irqrestore(&priv->lock, flags); | 568 | spin_unlock_irqrestore(&priv->lock, flags); |
412 | return rc; | 569 | return ret; |
413 | } | 570 | } |
414 | 571 | ||
415 | if (priv->cfg->mod_params->amsdu_size_8K) | 572 | if (priv->cfg->mod_params->amsdu_size_8K) |
@@ -429,15 +586,15 @@ static int iwl4965_rx_init(struct iwl_priv *priv, struct iwl4965_rx_queue *rxq) | |||
429 | 586 | ||
430 | /* Tell device where in DRAM to update its Rx status */ | 587 | /* Tell device where in DRAM to update its Rx status */ |
431 | iwl_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG, | 588 | iwl_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG, |
432 | (priv->hw_setting.shared_phys + | 589 | (priv->shared_phys + |
433 | offsetof(struct iwl4965_shared, val0)) >> 4); | 590 | offsetof(struct iwl4965_shared, rb_closed)) >> 4); |
434 | 591 | ||
435 | /* Enable Rx DMA, enable host interrupt, Rx buffer size 4k, 256 RBDs */ | 592 | /* Enable Rx DMA, enable host interrupt, Rx buffer size 4k, 256 RBDs */ |
436 | iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, | 593 | iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, |
437 | FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL | | 594 | FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL | |
438 | FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL | | 595 | FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL | |
439 | rb_size | | 596 | rb_size | |
440 | /*0x10 << 4 | */ | 597 | /* 0x10 << 4 | */ |
441 | (RX_QUEUE_SIZE_LOG << | 598 | (RX_QUEUE_SIZE_LOG << |
442 | FH_RCSR_RX_CONFIG_RBDCB_SIZE_BITSHIFT)); | 599 | FH_RCSR_RX_CONFIG_RBDCB_SIZE_BITSHIFT)); |
443 | 600 | ||
@@ -545,7 +702,7 @@ static int iwl4965_txq_ctx_reset(struct iwl_priv *priv) | |||
545 | 702 | ||
546 | /* Alloc and init all (default 16) Tx queues, | 703 | /* Alloc and init all (default 16) Tx queues, |
547 | * including the command queue (#4) */ | 704 | * including the command queue (#4) */ |
548 | for (txq_id = 0; txq_id < priv->hw_setting.max_txq_num; txq_id++) { | 705 | for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { |
549 | slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ? | 706 | slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ? |
550 | TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; | 707 | TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; |
551 | rc = iwl4965_tx_queue_init(priv, &priv->txq[txq_id], slots_num, | 708 | rc = iwl4965_tx_queue_init(priv, &priv->txq[txq_id], slots_num, |
@@ -751,7 +908,7 @@ void iwl4965_hw_txq_ctx_stop(struct iwl_priv *priv) | |||
751 | unsigned long flags; | 908 | unsigned long flags; |
752 | 909 | ||
753 | /* Stop each Tx DMA channel, and wait for it to be idle */ | 910 | /* Stop each Tx DMA channel, and wait for it to be idle */ |
754 | for (txq_id = 0; txq_id < priv->hw_setting.max_txq_num; txq_id++) { | 911 | for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { |
755 | spin_lock_irqsave(&priv->lock, flags); | 912 | spin_lock_irqsave(&priv->lock, flags); |
756 | if (iwl_grab_nic_access(priv)) { | 913 | if (iwl_grab_nic_access(priv)) { |
757 | spin_unlock_irqrestore(&priv->lock, flags); | 914 | spin_unlock_irqrestore(&priv->lock, flags); |
@@ -819,40 +976,21 @@ int iwl4965_hw_nic_reset(struct iwl_priv *priv) | |||
819 | /** | 976 | /** |
820 | * iwl4965_bg_statistics_periodic - Timer callback to queue statistics | 977 | * iwl4965_bg_statistics_periodic - Timer callback to queue statistics |
821 | * | 978 | * |
822 | * This callback is provided in order to queue the statistics_work | 979 | * This callback is provided in order to send a statistics request. |
823 | * in work_queue context (v. softirq) | ||
824 | * | 980 | * |
825 | * This timer function is continually reset to execute within | 981 | * This timer function is continually reset to execute within |
826 | * REG_RECALIB_PERIOD seconds since the last STATISTICS_NOTIFICATION | 982 | * REG_RECALIB_PERIOD seconds since the last STATISTICS_NOTIFICATION |
827 | * was received. We need to ensure we receive the statistics in order | 983 | * was received. We need to ensure we receive the statistics in order |
828 | * to update the temperature used for calibrating the TXPOWER. However, | 984 | * to update the temperature used for calibrating the TXPOWER. |
829 | * we can't send the statistics command from softirq context (which | ||
830 | * is the context which timers run at) so we have to queue off the | ||
831 | * statistics_work to actually send the command to the hardware. | ||
832 | */ | 985 | */ |
833 | static void iwl4965_bg_statistics_periodic(unsigned long data) | 986 | static void iwl4965_bg_statistics_periodic(unsigned long data) |
834 | { | 987 | { |
835 | struct iwl_priv *priv = (struct iwl_priv *)data; | 988 | struct iwl_priv *priv = (struct iwl_priv *)data; |
836 | 989 | ||
837 | queue_work(priv->workqueue, &priv->statistics_work); | ||
838 | } | ||
839 | |||
840 | /** | ||
841 | * iwl4965_bg_statistics_work - Send the statistics request to the hardware. | ||
842 | * | ||
843 | * This is queued by iwl4965_bg_statistics_periodic. | ||
844 | */ | ||
845 | static void iwl4965_bg_statistics_work(struct work_struct *work) | ||
846 | { | ||
847 | struct iwl_priv *priv = container_of(work, struct iwl_priv, | ||
848 | statistics_work); | ||
849 | |||
850 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 990 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
851 | return; | 991 | return; |
852 | 992 | ||
853 | mutex_lock(&priv->mutex); | 993 | iwl_send_statistics_request(priv, CMD_ASYNC); |
854 | iwl4965_send_statistics_request(priv); | ||
855 | mutex_unlock(&priv->mutex); | ||
856 | } | 994 | } |
857 | 995 | ||
858 | #define CT_LIMIT_CONST 259 | 996 | #define CT_LIMIT_CONST 259 |
@@ -1816,19 +1954,19 @@ int iwl4965_alive_notify(struct iwl_priv *priv) | |||
1816 | iwl_write_targ_mem(priv, a, 0); | 1954 | iwl_write_targ_mem(priv, a, 0); |
1817 | for (; a < priv->scd_base_addr + SCD_TRANSLATE_TBL_OFFSET; a += 4) | 1955 | for (; a < priv->scd_base_addr + SCD_TRANSLATE_TBL_OFFSET; a += 4) |
1818 | iwl_write_targ_mem(priv, a, 0); | 1956 | iwl_write_targ_mem(priv, a, 0); |
1819 | for (; a < sizeof(u16) * priv->hw_setting.max_txq_num; a += 4) | 1957 | for (; a < sizeof(u16) * priv->hw_params.max_txq_num; a += 4) |
1820 | iwl_write_targ_mem(priv, a, 0); | 1958 | iwl_write_targ_mem(priv, a, 0); |
1821 | 1959 | ||
1822 | /* Tel 4965 where to find Tx byte count tables */ | 1960 | /* Tel 4965 where to find Tx byte count tables */ |
1823 | iwl_write_prph(priv, IWL49_SCD_DRAM_BASE_ADDR, | 1961 | iwl_write_prph(priv, IWL49_SCD_DRAM_BASE_ADDR, |
1824 | (priv->hw_setting.shared_phys + | 1962 | (priv->shared_phys + |
1825 | offsetof(struct iwl4965_shared, queues_byte_cnt_tbls)) >> 10); | 1963 | offsetof(struct iwl4965_shared, queues_byte_cnt_tbls)) >> 10); |
1826 | 1964 | ||
1827 | /* Disable chain mode for all queues */ | 1965 | /* Disable chain mode for all queues */ |
1828 | iwl_write_prph(priv, IWL49_SCD_QUEUECHAIN_SEL, 0); | 1966 | iwl_write_prph(priv, IWL49_SCD_QUEUECHAIN_SEL, 0); |
1829 | 1967 | ||
1830 | /* Initialize each Tx queue (including the command queue) */ | 1968 | /* Initialize each Tx queue (including the command queue) */ |
1831 | for (i = 0; i < priv->hw_setting.max_txq_num; i++) { | 1969 | for (i = 0; i < priv->hw_params.max_txq_num; i++) { |
1832 | 1970 | ||
1833 | /* TFD circular buffer read/write indexes */ | 1971 | /* TFD circular buffer read/write indexes */ |
1834 | iwl_write_prph(priv, IWL49_SCD_QUEUE_RDPTR(i), 0); | 1972 | iwl_write_prph(priv, IWL49_SCD_QUEUE_RDPTR(i), 0); |
@@ -1851,7 +1989,7 @@ int iwl4965_alive_notify(struct iwl_priv *priv) | |||
1851 | 1989 | ||
1852 | } | 1990 | } |
1853 | iwl_write_prph(priv, IWL49_SCD_INTERRUPT_MASK, | 1991 | iwl_write_prph(priv, IWL49_SCD_INTERRUPT_MASK, |
1854 | (1 << priv->hw_setting.max_txq_num) - 1); | 1992 | (1 << priv->hw_params.max_txq_num) - 1); |
1855 | 1993 | ||
1856 | /* Activate all Tx DMA/FIFO channels */ | 1994 | /* Activate all Tx DMA/FIFO channels */ |
1857 | iwl_write_prph(priv, IWL49_SCD_TXFACT, | 1995 | iwl_write_prph(priv, IWL49_SCD_TXFACT, |
@@ -1869,55 +2007,45 @@ int iwl4965_alive_notify(struct iwl_priv *priv) | |||
1869 | iwl_release_nic_access(priv); | 2007 | iwl_release_nic_access(priv); |
1870 | spin_unlock_irqrestore(&priv->lock, flags); | 2008 | spin_unlock_irqrestore(&priv->lock, flags); |
1871 | 2009 | ||
2010 | /* Ask for statistics now, the uCode will send statistics notification | ||
2011 | * periodically after association */ | ||
2012 | iwl_send_statistics_request(priv, CMD_ASYNC); | ||
1872 | return ret; | 2013 | return ret; |
1873 | } | 2014 | } |
1874 | 2015 | ||
1875 | /** | 2016 | /** |
1876 | * iwl4965_hw_set_hw_setting | 2017 | * iwl4965_hw_set_hw_params |
1877 | * | 2018 | * |
1878 | * Called when initializing driver | 2019 | * Called when initializing driver |
1879 | */ | 2020 | */ |
1880 | int iwl4965_hw_set_hw_setting(struct iwl_priv *priv) | 2021 | int iwl4965_hw_set_hw_params(struct iwl_priv *priv) |
1881 | { | 2022 | { |
1882 | int ret = 0; | ||
1883 | 2023 | ||
1884 | if ((priv->cfg->mod_params->num_of_queues > IWL_MAX_NUM_QUEUES) || | 2024 | if ((priv->cfg->mod_params->num_of_queues > IWL4965_MAX_NUM_QUEUES) || |
1885 | (priv->cfg->mod_params->num_of_queues < IWL_MIN_NUM_QUEUES)) { | 2025 | (priv->cfg->mod_params->num_of_queues < IWL_MIN_NUM_QUEUES)) { |
1886 | IWL_ERROR("invalid queues_num, should be between %d and %d\n", | 2026 | IWL_ERROR("invalid queues_num, should be between %d and %d\n", |
1887 | IWL_MIN_NUM_QUEUES, IWL_MAX_NUM_QUEUES); | 2027 | IWL_MIN_NUM_QUEUES, IWL4965_MAX_NUM_QUEUES); |
1888 | ret = -EINVAL; | 2028 | return -EINVAL; |
1889 | goto out; | ||
1890 | } | ||
1891 | |||
1892 | /* Allocate area for Tx byte count tables and Rx queue status */ | ||
1893 | priv->hw_setting.shared_virt = | ||
1894 | pci_alloc_consistent(priv->pci_dev, | ||
1895 | sizeof(struct iwl4965_shared), | ||
1896 | &priv->hw_setting.shared_phys); | ||
1897 | |||
1898 | if (!priv->hw_setting.shared_virt) { | ||
1899 | ret = -ENOMEM; | ||
1900 | goto out; | ||
1901 | } | 2029 | } |
1902 | 2030 | ||
1903 | memset(priv->hw_setting.shared_virt, 0, sizeof(struct iwl4965_shared)); | 2031 | priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues; |
1904 | 2032 | priv->hw_params.tx_cmd_len = sizeof(struct iwl4965_tx_cmd); | |
1905 | priv->hw_setting.max_txq_num = priv->cfg->mod_params->num_of_queues; | 2033 | priv->hw_params.max_rxq_size = RX_QUEUE_SIZE; |
1906 | priv->hw_setting.tx_cmd_len = sizeof(struct iwl4965_tx_cmd); | 2034 | priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG; |
1907 | priv->hw_setting.max_rxq_size = RX_QUEUE_SIZE; | ||
1908 | priv->hw_setting.max_rxq_log = RX_QUEUE_SIZE_LOG; | ||
1909 | if (priv->cfg->mod_params->amsdu_size_8K) | 2035 | if (priv->cfg->mod_params->amsdu_size_8K) |
1910 | priv->hw_setting.rx_buf_size = IWL_RX_BUF_SIZE_8K; | 2036 | priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_8K; |
1911 | else | 2037 | else |
1912 | priv->hw_setting.rx_buf_size = IWL_RX_BUF_SIZE_4K; | 2038 | priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_4K; |
1913 | priv->hw_setting.max_pkt_size = priv->hw_setting.rx_buf_size - 256; | 2039 | priv->hw_params.max_pkt_size = priv->hw_params.rx_buf_size - 256; |
1914 | priv->hw_setting.max_stations = IWL4965_STATION_COUNT; | 2040 | priv->hw_params.max_stations = IWL4965_STATION_COUNT; |
1915 | priv->hw_setting.bcast_sta_id = IWL4965_BROADCAST_ID; | 2041 | priv->hw_params.bcast_sta_id = IWL4965_BROADCAST_ID; |
1916 | 2042 | ||
1917 | priv->hw_setting.tx_ant_num = 2; | 2043 | priv->hw_params.tx_chains_num = 2; |
2044 | priv->hw_params.rx_chains_num = 2; | ||
2045 | priv->hw_params.valid_tx_ant = (IWL_ANTENNA_MAIN | IWL_ANTENNA_AUX); | ||
2046 | priv->hw_params.valid_rx_ant = (IWL_ANTENNA_MAIN | IWL_ANTENNA_AUX); | ||
1918 | 2047 | ||
1919 | out: | 2048 | return 0; |
1920 | return ret; | ||
1921 | } | 2049 | } |
1922 | 2050 | ||
1923 | /** | 2051 | /** |
@@ -1930,7 +2058,7 @@ void iwl4965_hw_txq_ctx_free(struct iwl_priv *priv) | |||
1930 | int txq_id; | 2058 | int txq_id; |
1931 | 2059 | ||
1932 | /* Tx queues */ | 2060 | /* Tx queues */ |
1933 | for (txq_id = 0; txq_id < priv->hw_setting.max_txq_num; txq_id++) | 2061 | for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) |
1934 | iwl4965_tx_queue_free(priv, &priv->txq[txq_id]); | 2062 | iwl4965_tx_queue_free(priv, &priv->txq[txq_id]); |
1935 | 2063 | ||
1936 | /* Keep-warm buffer */ | 2064 | /* Keep-warm buffer */ |
@@ -2756,6 +2884,46 @@ out: | |||
2756 | return ret; | 2884 | return ret; |
2757 | } | 2885 | } |
2758 | 2886 | ||
2887 | static int iwl4965_send_rxon_assoc(struct iwl_priv *priv) | ||
2888 | { | ||
2889 | int ret = 0; | ||
2890 | struct iwl4965_rxon_assoc_cmd rxon_assoc; | ||
2891 | const struct iwl4965_rxon_cmd *rxon1 = &priv->staging_rxon; | ||
2892 | const struct iwl4965_rxon_cmd *rxon2 = &priv->active_rxon; | ||
2893 | |||
2894 | if ((rxon1->flags == rxon2->flags) && | ||
2895 | (rxon1->filter_flags == rxon2->filter_flags) && | ||
2896 | (rxon1->cck_basic_rates == rxon2->cck_basic_rates) && | ||
2897 | (rxon1->ofdm_ht_single_stream_basic_rates == | ||
2898 | rxon2->ofdm_ht_single_stream_basic_rates) && | ||
2899 | (rxon1->ofdm_ht_dual_stream_basic_rates == | ||
2900 | rxon2->ofdm_ht_dual_stream_basic_rates) && | ||
2901 | (rxon1->rx_chain == rxon2->rx_chain) && | ||
2902 | (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) { | ||
2903 | IWL_DEBUG_INFO("Using current RXON_ASSOC. Not resending.\n"); | ||
2904 | return 0; | ||
2905 | } | ||
2906 | |||
2907 | rxon_assoc.flags = priv->staging_rxon.flags; | ||
2908 | rxon_assoc.filter_flags = priv->staging_rxon.filter_flags; | ||
2909 | rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates; | ||
2910 | rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates; | ||
2911 | rxon_assoc.reserved = 0; | ||
2912 | rxon_assoc.ofdm_ht_single_stream_basic_rates = | ||
2913 | priv->staging_rxon.ofdm_ht_single_stream_basic_rates; | ||
2914 | rxon_assoc.ofdm_ht_dual_stream_basic_rates = | ||
2915 | priv->staging_rxon.ofdm_ht_dual_stream_basic_rates; | ||
2916 | rxon_assoc.rx_chain_select_flags = priv->staging_rxon.rx_chain; | ||
2917 | |||
2918 | ret = iwl_send_cmd_pdu_async(priv, REPLY_RXON_ASSOC, | ||
2919 | sizeof(rxon_assoc), &rxon_assoc, NULL); | ||
2920 | if (ret) | ||
2921 | return ret; | ||
2922 | |||
2923 | return ret; | ||
2924 | } | ||
2925 | |||
2926 | |||
2759 | int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel) | 2927 | int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel) |
2760 | { | 2928 | { |
2761 | int rc; | 2929 | int rc; |
@@ -2869,9 +3037,8 @@ void iwl4965_hw_build_tx_cmd_rate(struct iwl_priv *priv, | |||
2869 | 3037 | ||
2870 | int iwl4965_hw_get_rx_read(struct iwl_priv *priv) | 3038 | int iwl4965_hw_get_rx_read(struct iwl_priv *priv) |
2871 | { | 3039 | { |
2872 | struct iwl4965_shared *shared_data = priv->hw_setting.shared_virt; | 3040 | struct iwl4965_shared *s = priv->shared_virt; |
2873 | 3041 | return le32_to_cpu(s->rb_closed) & 0xFFF; | |
2874 | return IWL_GET_BITS(*shared_data, rb_closed_stts_rb_num); | ||
2875 | } | 3042 | } |
2876 | 3043 | ||
2877 | int iwl4965_hw_get_temperature(struct iwl_priv *priv) | 3044 | int iwl4965_hw_get_temperature(struct iwl_priv *priv) |
@@ -2888,7 +3055,7 @@ unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv, | |||
2888 | tx_beacon_cmd = &frame->u.beacon; | 3055 | tx_beacon_cmd = &frame->u.beacon; |
2889 | memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd)); | 3056 | memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd)); |
2890 | 3057 | ||
2891 | tx_beacon_cmd->tx.sta_id = priv->hw_setting.bcast_sta_id; | 3058 | tx_beacon_cmd->tx.sta_id = priv->hw_params.bcast_sta_id; |
2892 | tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; | 3059 | tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; |
2893 | 3060 | ||
2894 | frame_size = iwl4965_fill_beacon_frame(priv, | 3061 | frame_size = iwl4965_fill_beacon_frame(priv, |
@@ -2996,17 +3163,15 @@ static void iwl4965_hw_card_show_info(struct iwl_priv *priv) | |||
2996 | #define IWL_TX_DELIMITER_SIZE 4 | 3163 | #define IWL_TX_DELIMITER_SIZE 4 |
2997 | 3164 | ||
2998 | /** | 3165 | /** |
2999 | * iwl4965_tx_queue_update_wr_ptr - Set up entry in Tx byte-count array | 3166 | * iwl4965_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array |
3000 | */ | 3167 | */ |
3001 | int iwl4965_tx_queue_update_wr_ptr(struct iwl_priv *priv, | 3168 | static void iwl4965_txq_update_byte_cnt_tbl(struct iwl_priv *priv, |
3002 | struct iwl4965_tx_queue *txq, u16 byte_cnt) | 3169 | struct iwl4965_tx_queue *txq, |
3170 | u16 byte_cnt) | ||
3003 | { | 3171 | { |
3004 | int len; | 3172 | int len; |
3005 | int txq_id = txq->q.id; | 3173 | int txq_id = txq->q.id; |
3006 | struct iwl4965_shared *shared_data = priv->hw_setting.shared_virt; | 3174 | struct iwl4965_shared *shared_data = priv->shared_virt; |
3007 | |||
3008 | if (txq->need_update == 0) | ||
3009 | return 0; | ||
3010 | 3175 | ||
3011 | len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE; | 3176 | len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE; |
3012 | 3177 | ||
@@ -3019,8 +3184,6 @@ int iwl4965_tx_queue_update_wr_ptr(struct iwl_priv *priv, | |||
3019 | IWL_SET_BITS16(shared_data->queues_byte_cnt_tbls[txq_id]. | 3184 | IWL_SET_BITS16(shared_data->queues_byte_cnt_tbls[txq_id]. |
3020 | tfd_offset[IWL4965_QUEUE_SIZE + txq->q.write_ptr], | 3185 | tfd_offset[IWL4965_QUEUE_SIZE + txq->q.write_ptr], |
3021 | byte_cnt, len); | 3186 | byte_cnt, len); |
3022 | |||
3023 | return 0; | ||
3024 | } | 3187 | } |
3025 | 3188 | ||
3026 | /** | 3189 | /** |
@@ -3500,7 +3663,7 @@ static void iwl4965_handle_data_packet(struct iwl_priv *priv, int is_data, | |||
3500 | rx_start->byte_count = amsdu->byte_count; | 3663 | rx_start->byte_count = amsdu->byte_count; |
3501 | rx_end = (__le32 *) (((u8 *) hdr) + len); | 3664 | rx_end = (__le32 *) (((u8 *) hdr) + len); |
3502 | } | 3665 | } |
3503 | if (len > priv->hw_setting.max_pkt_size || len < 16) { | 3666 | if (len > priv->hw_params.max_pkt_size || len < 16) { |
3504 | IWL_WARNING("byte count out of range [16,4K] : %d\n", len); | 3667 | IWL_WARNING("byte count out of range [16,4K] : %d\n", len); |
3505 | return; | 3668 | return; |
3506 | } | 3669 | } |
@@ -3528,7 +3691,7 @@ static void iwl4965_handle_data_packet(struct iwl_priv *priv, int is_data, | |||
3528 | stats->flag = 0; | 3691 | stats->flag = 0; |
3529 | hdr = (struct ieee80211_hdr *)rxb->skb->data; | 3692 | hdr = (struct ieee80211_hdr *)rxb->skb->data; |
3530 | 3693 | ||
3531 | if (priv->cfg->mod_params->hw_crypto) | 3694 | if (!priv->cfg->mod_params->sw_crypto) |
3532 | iwl4965_set_decrypted_flag(priv, rxb->skb, ampdu_status, stats); | 3695 | iwl4965_set_decrypted_flag(priv, rxb->skb, ampdu_status, stats); |
3533 | 3696 | ||
3534 | if (priv->add_radiotap) | 3697 | if (priv->add_radiotap) |
@@ -4199,7 +4362,7 @@ static void iwl4965_rx_reply_compressed_ba(struct iwl_priv *priv, | |||
4199 | * (in Tx queue's circular buffer) of first TFD/frame in window */ | 4362 | * (in Tx queue's circular buffer) of first TFD/frame in window */ |
4200 | u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn); | 4363 | u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn); |
4201 | 4364 | ||
4202 | if (scd_flow >= ARRAY_SIZE(priv->txq)) { | 4365 | if (scd_flow >= priv->hw_params.max_txq_num) { |
4203 | IWL_ERROR("BUG_ON scd_flow is bigger than number of queues"); | 4366 | IWL_ERROR("BUG_ON scd_flow is bigger than number of queues"); |
4204 | return; | 4367 | return; |
4205 | } | 4368 | } |
@@ -4361,7 +4524,7 @@ static int iwl4965_tx_queue_agg_enable(struct iwl_priv *priv, int txq_id, | |||
4361 | void iwl4965_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap) | 4524 | void iwl4965_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap) |
4362 | { | 4525 | { |
4363 | int i, r; | 4526 | int i, r; |
4364 | struct iwl4965_link_quality_cmd link_cmd = { | 4527 | struct iwl_link_quality_cmd link_cmd = { |
4365 | .reserved1 = 0, | 4528 | .reserved1 = 0, |
4366 | }; | 4529 | }; |
4367 | u16 rate_flags; | 4530 | u16 rate_flags; |
@@ -4395,7 +4558,7 @@ void iwl4965_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap) | |||
4395 | link_cmd.agg_params.agg_time_limit = cpu_to_le16(4000); | 4558 | link_cmd.agg_params.agg_time_limit = cpu_to_le16(4000); |
4396 | 4559 | ||
4397 | /* Update the rate scaling for control frame Tx to AP */ | 4560 | /* Update the rate scaling for control frame Tx to AP */ |
4398 | link_cmd.sta_id = is_ap ? IWL_AP_ID : priv->hw_setting.bcast_sta_id; | 4561 | link_cmd.sta_id = is_ap ? IWL_AP_ID : priv->hw_params.bcast_sta_id; |
4399 | 4562 | ||
4400 | iwl_send_cmd_pdu_async(priv, REPLY_TX_LINK_QUALITY_CMD, | 4563 | iwl_send_cmd_pdu_async(priv, REPLY_TX_LINK_QUALITY_CMD, |
4401 | sizeof(link_cmd), &link_cmd, NULL); | 4564 | sizeof(link_cmd), &link_cmd, NULL); |
@@ -4584,7 +4747,7 @@ static int iwl4965_txq_ctx_activate_free(struct iwl_priv *priv) | |||
4584 | { | 4747 | { |
4585 | int txq_id; | 4748 | int txq_id; |
4586 | 4749 | ||
4587 | for (txq_id = 0; txq_id < priv->hw_setting.max_txq_num; txq_id++) | 4750 | for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) |
4588 | if (!test_and_set_bit(txq_id, &priv->txq_ctx_active_msk)) | 4751 | if (!test_and_set_bit(txq_id, &priv->txq_ctx_active_msk)) |
4589 | return txq_id; | 4752 | return txq_id; |
4590 | return -1; | 4753 | return -1; |
@@ -4767,7 +4930,6 @@ void iwl4965_hw_rx_handler_setup(struct iwl_priv *priv) | |||
4767 | void iwl4965_hw_setup_deferred_work(struct iwl_priv *priv) | 4930 | void iwl4965_hw_setup_deferred_work(struct iwl_priv *priv) |
4768 | { | 4931 | { |
4769 | INIT_WORK(&priv->txpower_work, iwl4965_bg_txpower_work); | 4932 | INIT_WORK(&priv->txpower_work, iwl4965_bg_txpower_work); |
4770 | INIT_WORK(&priv->statistics_work, iwl4965_bg_statistics_work); | ||
4771 | #ifdef CONFIG_IWL4965_SENSITIVITY | 4933 | #ifdef CONFIG_IWL4965_SENSITIVITY |
4772 | INIT_WORK(&priv->sensitivity_work, iwl4965_bg_sensitivity_work); | 4934 | INIT_WORK(&priv->sensitivity_work, iwl4965_bg_sensitivity_work); |
4773 | #endif | 4935 | #endif |
@@ -4783,12 +4945,23 @@ void iwl4965_hw_cancel_deferred_work(struct iwl_priv *priv) | |||
4783 | cancel_delayed_work(&priv->init_alive_start); | 4945 | cancel_delayed_work(&priv->init_alive_start); |
4784 | } | 4946 | } |
4785 | 4947 | ||
4948 | |||
4949 | static struct iwl_hcmd_ops iwl4965_hcmd = { | ||
4950 | .rxon_assoc = iwl4965_send_rxon_assoc, | ||
4951 | }; | ||
4952 | |||
4786 | static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = { | 4953 | static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = { |
4787 | .enqueue_hcmd = iwl4965_enqueue_hcmd, | 4954 | .enqueue_hcmd = iwl4965_enqueue_hcmd, |
4788 | }; | 4955 | }; |
4789 | 4956 | ||
4790 | static struct iwl_lib_ops iwl4965_lib = { | 4957 | static struct iwl_lib_ops iwl4965_lib = { |
4791 | .init_drv = iwl4965_init_drv, | 4958 | .init_drv = iwl4965_init_drv, |
4959 | .set_hw_params = iwl4965_hw_set_hw_params, | ||
4960 | .txq_update_byte_cnt_tbl = iwl4965_txq_update_byte_cnt_tbl, | ||
4961 | .hw_nic_init = iwl4965_hw_nic_init, | ||
4962 | .is_valid_rtc_data_addr = iwl4965_hw_valid_rtc_data_addr, | ||
4963 | .alive_notify = iwl4965_alive_notify, | ||
4964 | .load_ucode = iwl4965_load_bsm, | ||
4792 | .eeprom_ops = { | 4965 | .eeprom_ops = { |
4793 | .verify_signature = iwlcore_eeprom_verify_signature, | 4966 | .verify_signature = iwlcore_eeprom_verify_signature, |
4794 | .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, | 4967 | .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, |
@@ -4799,10 +4972,11 @@ static struct iwl_lib_ops iwl4965_lib = { | |||
4799 | 4972 | ||
4800 | static struct iwl_ops iwl4965_ops = { | 4973 | static struct iwl_ops iwl4965_ops = { |
4801 | .lib = &iwl4965_lib, | 4974 | .lib = &iwl4965_lib, |
4975 | .hcmd = &iwl4965_hcmd, | ||
4802 | .utils = &iwl4965_hcmd_utils, | 4976 | .utils = &iwl4965_hcmd_utils, |
4803 | }; | 4977 | }; |
4804 | 4978 | ||
4805 | static struct iwl_cfg iwl4965_agn_cfg = { | 4979 | struct iwl_cfg iwl4965_agn_cfg = { |
4806 | .name = "4965AGN", | 4980 | .name = "4965AGN", |
4807 | .fw_name = "iwlwifi-4965" IWL4965_UCODE_API ".ucode", | 4981 | .fw_name = "iwlwifi-4965" IWL4965_UCODE_API ".ucode", |
4808 | .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, | 4982 | .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, |
@@ -4810,21 +4984,12 @@ static struct iwl_cfg iwl4965_agn_cfg = { | |||
4810 | .mod_params = &iwl4965_mod_params, | 4984 | .mod_params = &iwl4965_mod_params, |
4811 | }; | 4985 | }; |
4812 | 4986 | ||
4813 | struct pci_device_id iwl4965_hw_card_ids[] = { | ||
4814 | {IWL_PCI_DEVICE(0x4229, PCI_ANY_ID, iwl4965_agn_cfg)}, | ||
4815 | {IWL_PCI_DEVICE(0x4230, PCI_ANY_ID, iwl4965_agn_cfg)}, | ||
4816 | {0} | ||
4817 | }; | ||
4818 | |||
4819 | MODULE_DEVICE_TABLE(pci, iwl4965_hw_card_ids); | ||
4820 | |||
4821 | module_param_named(antenna, iwl4965_mod_params.antenna, int, 0444); | 4987 | module_param_named(antenna, iwl4965_mod_params.antenna, int, 0444); |
4822 | MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])"); | 4988 | MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])"); |
4823 | module_param_named(disable, iwl4965_mod_params.disable, int, 0444); | 4989 | module_param_named(disable, iwl4965_mod_params.disable, int, 0444); |
4824 | MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])"); | 4990 | MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])"); |
4825 | module_param_named(hwcrypto, iwl4965_mod_params.hw_crypto, int, 0444); | 4991 | module_param_named(swcrypto, iwl4965_mod_params.sw_crypto, int, 0444); |
4826 | MODULE_PARM_DESC(hwcrypto, | 4992 | MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])\n"); |
4827 | "using hardware crypto engine (default 0 [software])\n"); | ||
4828 | module_param_named(debug, iwl4965_mod_params.debug, int, 0444); | 4993 | module_param_named(debug, iwl4965_mod_params.debug, int, 0444); |
4829 | MODULE_PARM_DESC(debug, "debug output mask"); | 4994 | MODULE_PARM_DESC(debug, "debug output mask"); |
4830 | module_param_named( | 4995 | module_param_named( |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.h b/drivers/net/wireless/iwlwifi/iwl-4965.h index 65e536782706..9ed13cb0a2a9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965.h | |||
@@ -36,9 +36,6 @@ | |||
36 | #include <linux/kernel.h> | 36 | #include <linux/kernel.h> |
37 | #include <net/ieee80211_radiotap.h> | 37 | #include <net/ieee80211_radiotap.h> |
38 | 38 | ||
39 | /* Hardware specific file defines the PCI IDs table for that hardware module */ | ||
40 | extern struct pci_device_id iwl4965_hw_card_ids[]; | ||
41 | |||
42 | #define DRV_NAME "iwl4965" | 39 | #define DRV_NAME "iwl4965" |
43 | #include "iwl-rfkill.h" | 40 | #include "iwl-rfkill.h" |
44 | #include "iwl-eeprom.h" | 41 | #include "iwl-eeprom.h" |
@@ -48,6 +45,9 @@ extern struct pci_device_id iwl4965_hw_card_ids[]; | |||
48 | #include "iwl-debug.h" | 45 | #include "iwl-debug.h" |
49 | #include "iwl-led.h" | 46 | #include "iwl-led.h" |
50 | 47 | ||
48 | /* configuration for the iwl4965 */ | ||
49 | extern struct iwl_cfg iwl4965_agn_cfg; | ||
50 | |||
51 | /* Change firmware file name, using "-" and incrementing number, | 51 | /* Change firmware file name, using "-" and incrementing number, |
52 | * *only* when uCode interface or architecture changes so that it | 52 | * *only* when uCode interface or architecture changes so that it |
53 | * is not compatible with earlier drivers. | 53 | * is not compatible with earlier drivers. |
@@ -461,6 +461,7 @@ struct iwl4965_tid_data { | |||
461 | struct iwl4965_hw_key { | 461 | struct iwl4965_hw_key { |
462 | enum ieee80211_key_alg alg; | 462 | enum ieee80211_key_alg alg; |
463 | int keylen; | 463 | int keylen; |
464 | u8 keyidx; | ||
464 | struct ieee80211_key_conf *conf; | 465 | struct ieee80211_key_conf *conf; |
465 | u8 key[32]; | 466 | u8 key[32]; |
466 | }; | 467 | }; |
@@ -566,7 +567,7 @@ struct iwl4965_ibss_seq { | |||
566 | }; | 567 | }; |
567 | 568 | ||
568 | /** | 569 | /** |
569 | * struct iwl4965_driver_hw_info | 570 | * struct iwl_hw_params |
570 | * @max_txq_num: Max # Tx queues supported | 571 | * @max_txq_num: Max # Tx queues supported |
571 | * @tx_cmd_len: Size of Tx command (but not including frame itself) | 572 | * @tx_cmd_len: Size of Tx command (but not including frame itself) |
572 | * @tx_ant_num: Number of TX antennas | 573 | * @tx_ant_num: Number of TX antennas |
@@ -575,21 +576,20 @@ struct iwl4965_ibss_seq { | |||
575 | * @max_rxq_log: Log-base-2 of max_rxq_size | 576 | * @max_rxq_log: Log-base-2 of max_rxq_size |
576 | * @max_stations: | 577 | * @max_stations: |
577 | * @bcast_sta_id: | 578 | * @bcast_sta_id: |
578 | * @shared_virt: Pointer to driver/uCode shared Tx Byte Counts and Rx status | ||
579 | * @shared_phys: Physical Pointer to Tx Byte Counts and Rx status | ||
580 | */ | 579 | */ |
581 | struct iwl4965_driver_hw_info { | 580 | struct iwl_hw_params { |
582 | u16 max_txq_num; | 581 | u16 max_txq_num; |
583 | u16 tx_cmd_len; | 582 | u16 tx_cmd_len; |
584 | u16 tx_ant_num; | 583 | u8 tx_chains_num; |
584 | u8 rx_chains_num; | ||
585 | u8 valid_tx_ant; | ||
586 | u8 valid_rx_ant; | ||
585 | u16 max_rxq_size; | 587 | u16 max_rxq_size; |
588 | u16 max_rxq_log; | ||
586 | u32 rx_buf_size; | 589 | u32 rx_buf_size; |
587 | u32 max_pkt_size; | 590 | u32 max_pkt_size; |
588 | u16 max_rxq_log; | ||
589 | u8 max_stations; | 591 | u8 max_stations; |
590 | u8 bcast_sta_id; | 592 | u8 bcast_sta_id; |
591 | void *shared_virt; | ||
592 | dma_addr_t shared_phys; | ||
593 | }; | 593 | }; |
594 | 594 | ||
595 | #define HT_SHORT_GI_20MHZ_ONLY (1 << 0) | 595 | #define HT_SHORT_GI_20MHZ_ONLY (1 << 0) |
@@ -641,7 +641,6 @@ extern unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv, | |||
641 | const u8 *dest, int left); | 641 | const u8 *dest, int left); |
642 | extern int iwl4965_rx_queue_update_write_ptr(struct iwl_priv *priv, | 642 | extern int iwl4965_rx_queue_update_write_ptr(struct iwl_priv *priv, |
643 | struct iwl4965_rx_queue *q); | 643 | struct iwl4965_rx_queue *q); |
644 | extern int iwl4965_send_statistics_request(struct iwl_priv *priv); | ||
645 | extern void iwl4965_set_decrypted_flag(struct iwl_priv *priv, struct sk_buff *skb, | 644 | extern void iwl4965_set_decrypted_flag(struct iwl_priv *priv, struct sk_buff *skb, |
646 | u32 decrypt_res, | 645 | u32 decrypt_res, |
647 | struct ieee80211_rx_status *stats); | 646 | struct ieee80211_rx_status *stats); |
@@ -679,7 +678,7 @@ extern void iwl4965_hw_rx_handler_setup(struct iwl_priv *priv); | |||
679 | extern void iwl4965_hw_setup_deferred_work(struct iwl_priv *priv); | 678 | extern void iwl4965_hw_setup_deferred_work(struct iwl_priv *priv); |
680 | extern void iwl4965_hw_cancel_deferred_work(struct iwl_priv *priv); | 679 | extern void iwl4965_hw_cancel_deferred_work(struct iwl_priv *priv); |
681 | extern int iwl4965_hw_rxq_stop(struct iwl_priv *priv); | 680 | extern int iwl4965_hw_rxq_stop(struct iwl_priv *priv); |
682 | extern int iwl4965_hw_set_hw_setting(struct iwl_priv *priv); | 681 | extern int iwl4965_hw_set_hw_params(struct iwl_priv *priv); |
683 | extern int iwl4965_hw_nic_init(struct iwl_priv *priv); | 682 | extern int iwl4965_hw_nic_init(struct iwl_priv *priv); |
684 | extern int iwl4965_hw_nic_stop_master(struct iwl_priv *priv); | 683 | extern int iwl4965_hw_nic_stop_master(struct iwl_priv *priv); |
685 | extern void iwl4965_hw_txq_ctx_free(struct iwl_priv *priv); | 684 | extern void iwl4965_hw_txq_ctx_free(struct iwl_priv *priv); |
@@ -942,6 +941,8 @@ enum { | |||
942 | 941 | ||
943 | #endif | 942 | #endif |
944 | 943 | ||
944 | #define IWL_MAX_NUM_QUEUES 20 /* FIXME: do dynamic allocation */ | ||
945 | |||
945 | struct iwl_priv { | 946 | struct iwl_priv { |
946 | 947 | ||
947 | /* ieee device used by generic ieee processing code */ | 948 | /* ieee device used by generic ieee processing code */ |
@@ -1033,7 +1034,7 @@ struct iwl_priv { | |||
1033 | * 4965's initialize alive response contains some calibration data. */ | 1034 | * 4965's initialize alive response contains some calibration data. */ |
1034 | struct iwl4965_init_alive_resp card_alive_init; | 1035 | struct iwl4965_init_alive_resp card_alive_init; |
1035 | struct iwl4965_alive_resp card_alive; | 1036 | struct iwl4965_alive_resp card_alive; |
1036 | #ifdef CONFIG_IWLCORE_RFKILL | 1037 | #ifdef CONFIG_IWLWIFI_RFKILL |
1037 | struct iwl_rfkill_mngr rfkill_mngr; | 1038 | struct iwl_rfkill_mngr rfkill_mngr; |
1038 | #endif | 1039 | #endif |
1039 | 1040 | ||
@@ -1112,6 +1113,10 @@ struct iwl_priv { | |||
1112 | spinlock_t sta_lock; | 1113 | spinlock_t sta_lock; |
1113 | int num_stations; | 1114 | int num_stations; |
1114 | struct iwl4965_station_entry stations[IWL_STATION_COUNT]; | 1115 | struct iwl4965_station_entry stations[IWL_STATION_COUNT]; |
1116 | struct iwl_wep_key wep_keys[WEP_KEYS_MAX]; | ||
1117 | u8 default_wep_key; | ||
1118 | u8 key_mapping_key; | ||
1119 | unsigned long ucode_key_table; | ||
1115 | 1120 | ||
1116 | /* Indication if ieee80211_ops->open has been called */ | 1121 | /* Indication if ieee80211_ops->open has been called */ |
1117 | u8 is_open; | 1122 | u8 is_open; |
@@ -1142,9 +1147,14 @@ struct iwl_priv { | |||
1142 | /* Last Rx'd beacon timestamp */ | 1147 | /* Last Rx'd beacon timestamp */ |
1143 | u64 timestamp; | 1148 | u64 timestamp; |
1144 | u16 beacon_int; | 1149 | u16 beacon_int; |
1145 | struct iwl4965_driver_hw_info hw_setting; | ||
1146 | struct ieee80211_vif *vif; | 1150 | struct ieee80211_vif *vif; |
1147 | 1151 | ||
1152 | struct iwl_hw_params hw_params; | ||
1153 | /* driver/uCode shared Tx Byte Counts and Rx status */ | ||
1154 | void *shared_virt; | ||
1155 | /* Physical Pointer to Tx Byte Counts and Rx status */ | ||
1156 | dma_addr_t shared_phys; | ||
1157 | |||
1148 | /* Current association information needed to configure the | 1158 | /* Current association information needed to configure the |
1149 | * hardware */ | 1159 | * hardware */ |
1150 | u16 assoc_id; | 1160 | u16 assoc_id; |
@@ -1200,7 +1210,6 @@ struct iwl_priv { | |||
1200 | #ifdef CONFIG_IWL4965_SENSITIVITY | 1210 | #ifdef CONFIG_IWL4965_SENSITIVITY |
1201 | struct work_struct sensitivity_work; | 1211 | struct work_struct sensitivity_work; |
1202 | #endif | 1212 | #endif |
1203 | struct work_struct statistics_work; | ||
1204 | struct timer_list statistics_periodic; | 1213 | struct timer_list statistics_periodic; |
1205 | }; /*iwl_priv */ | 1214 | }; /*iwl_priv */ |
1206 | 1215 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index d8a226e68ed1..2dfd982d7d1f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -277,3 +277,16 @@ int iwlcore_low_level_notify(struct iwl_priv *priv, | |||
277 | } | 277 | } |
278 | EXPORT_SYMBOL(iwlcore_low_level_notify); | 278 | EXPORT_SYMBOL(iwlcore_low_level_notify); |
279 | 279 | ||
280 | int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags) | ||
281 | { | ||
282 | u32 stat_flags = 0; | ||
283 | struct iwl_host_cmd cmd = { | ||
284 | .id = REPLY_STATISTICS_CMD, | ||
285 | .meta.flags = flags, | ||
286 | .len = sizeof(stat_flags), | ||
287 | .data = (u8 *) &stat_flags, | ||
288 | }; | ||
289 | return iwl_send_cmd(priv, &cmd); | ||
290 | } | ||
291 | EXPORT_SYMBOL(iwl_send_statistics_request); | ||
292 | |||
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 6d82376f43f9..7193d97630dc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -82,6 +82,9 @@ struct iwl_cmd; | |||
82 | #define IWL_SKU_A 0x2 | 82 | #define IWL_SKU_A 0x2 |
83 | #define IWL_SKU_N 0x8 | 83 | #define IWL_SKU_N 0x8 |
84 | 84 | ||
85 | struct iwl_hcmd_ops { | ||
86 | int (*rxon_assoc)(struct iwl_priv *priv); | ||
87 | }; | ||
85 | struct iwl_hcmd_utils_ops { | 88 | struct iwl_hcmd_utils_ops { |
86 | 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); |
87 | }; | 90 | }; |
@@ -89,19 +92,35 @@ struct iwl_hcmd_utils_ops { | |||
89 | struct iwl_lib_ops { | 92 | struct iwl_lib_ops { |
90 | /* iwlwifi driver (priv) init */ | 93 | /* iwlwifi driver (priv) init */ |
91 | int (*init_drv)(struct iwl_priv *priv); | 94 | int (*init_drv)(struct iwl_priv *priv); |
95 | /* set hw dependant perameters */ | ||
96 | int (*set_hw_params)(struct iwl_priv *priv); | ||
97 | |||
98 | void (*txq_update_byte_cnt_tbl)(struct iwl_priv *priv, | ||
99 | struct iwl4965_tx_queue *txq, | ||
100 | u16 byte_cnt); | ||
101 | /* nic init */ | ||
102 | int (*hw_nic_init)(struct iwl_priv *priv); | ||
103 | /* alive notification */ | ||
104 | int (*alive_notify)(struct iwl_priv *priv); | ||
105 | /* check validity of rtc data address */ | ||
106 | int (*is_valid_rtc_data_addr)(u32 addr); | ||
107 | /* 1st ucode load */ | ||
108 | int (*load_ucode)(struct iwl_priv *priv); | ||
109 | /* rfkill */ | ||
110 | void (*radio_kill_sw)(struct iwl_priv *priv, int disable_radio); | ||
92 | /* eeprom operations (as defined in iwl-eeprom.h) */ | 111 | /* eeprom operations (as defined in iwl-eeprom.h) */ |
93 | struct iwl_eeprom_ops eeprom_ops; | 112 | struct iwl_eeprom_ops eeprom_ops; |
94 | void (*radio_kill_sw)(struct iwl_priv *priv, int disable_radio); | ||
95 | }; | 113 | }; |
96 | 114 | ||
97 | struct iwl_ops { | 115 | struct iwl_ops { |
98 | const struct iwl_lib_ops *lib; | 116 | const struct iwl_lib_ops *lib; |
117 | const struct iwl_hcmd_ops *hcmd; | ||
99 | const struct iwl_hcmd_utils_ops *utils; | 118 | const struct iwl_hcmd_utils_ops *utils; |
100 | }; | 119 | }; |
101 | 120 | ||
102 | struct iwl_mod_params { | 121 | struct iwl_mod_params { |
103 | int disable; /* def: 0 = enable radio */ | 122 | int disable; /* def: 0 = enable radio */ |
104 | int hw_crypto; /* def: 0 = using software encryption */ | 123 | int sw_crypto; /* def: 0 = using hardware encryption */ |
105 | int debug; /* def: 0 = minimal debug log messages */ | 124 | int debug; /* def: 0 = minimal debug log messages */ |
106 | int disable_hw_scan; /* def: 0 = use h/w scan */ | 125 | int disable_hw_scan; /* def: 0 = use h/w scan */ |
107 | int num_of_queues; /* def: HW dependent */ | 126 | int num_of_queues; /* def: HW dependent */ |
@@ -215,4 +234,13 @@ enum iwlcore_card_notify { | |||
215 | 234 | ||
216 | int iwlcore_low_level_notify(struct iwl_priv *priv, | 235 | int iwlcore_low_level_notify(struct iwl_priv *priv, |
217 | enum iwlcore_card_notify notify); | 236 | enum iwlcore_card_notify notify); |
237 | extern int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags); | ||
238 | int iwl_send_lq_cmd(struct iwl_priv *priv, | ||
239 | struct iwl_link_quality_cmd *lq, u8 flags); | ||
240 | |||
241 | static inline int iwl_send_rxon_assoc(struct iwl_priv *priv) | ||
242 | { | ||
243 | return priv->cfg->ops->hcmd->rxon_assoc(priv); | ||
244 | } | ||
245 | |||
218 | #endif /* __iwl_core_h__ */ | 246 | #endif /* __iwl_core_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 23632e54aab2..0f16f2606f29 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c | |||
@@ -102,10 +102,14 @@ static ssize_t iwl_dbgfs_tx_statistics_read(struct file *file, | |||
102 | struct iwl_priv *priv = (struct iwl_priv *)file->private_data; | 102 | struct iwl_priv *priv = (struct iwl_priv *)file->private_data; |
103 | char buf[256]; | 103 | char buf[256]; |
104 | int pos = 0; | 104 | int pos = 0; |
105 | const size_t bufsz = sizeof(buf); | ||
105 | 106 | ||
106 | pos += sprintf(buf+pos, "mgmt: %u\n", priv->tx_stats[0].cnt); | 107 | pos += scnprintf(buf + pos, bufsz - pos, "mgmt: %u\n", |
107 | pos += sprintf(buf+pos, "ctrl: %u\n", priv->tx_stats[1].cnt); | 108 | priv->tx_stats[0].cnt); |
108 | pos += sprintf(buf+pos, "data: %u\n", priv->tx_stats[2].cnt); | 109 | pos += scnprintf(buf + pos, bufsz - pos, "ctrl: %u\n", |
110 | priv->tx_stats[1].cnt); | ||
111 | pos += scnprintf(buf + pos, bufsz - pos, "data: %u\n", | ||
112 | priv->tx_stats[2].cnt); | ||
109 | 113 | ||
110 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 114 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
111 | } | 115 | } |
@@ -117,10 +121,14 @@ static ssize_t iwl_dbgfs_rx_statistics_read(struct file *file, | |||
117 | struct iwl_priv *priv = (struct iwl_priv *)file->private_data; | 121 | struct iwl_priv *priv = (struct iwl_priv *)file->private_data; |
118 | char buf[256]; | 122 | char buf[256]; |
119 | int pos = 0; | 123 | int pos = 0; |
124 | const size_t bufsz = sizeof(buf); | ||
120 | 125 | ||
121 | pos += sprintf(buf+pos, "mgmt: %u\n", priv->rx_stats[0].cnt); | 126 | pos += scnprintf(buf + pos, bufsz - pos, "mgmt: %u\n", |
122 | pos += sprintf(buf+pos, "ctrl: %u\n", priv->rx_stats[1].cnt); | 127 | priv->rx_stats[0].cnt); |
123 | pos += sprintf(buf+pos, "data: %u\n", priv->rx_stats[2].cnt); | 128 | pos += scnprintf(buf + pos, bufsz - pos, "ctrl: %u\n", |
129 | priv->rx_stats[1].cnt); | ||
130 | pos += scnprintf(buf + pos, bufsz - pos, "data: %u\n", | ||
131 | priv->rx_stats[2].cnt); | ||
124 | 132 | ||
125 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 133 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
126 | } | 134 | } |
@@ -138,6 +146,7 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, | |||
138 | int i; | 146 | int i; |
139 | int pos = 0; | 147 | int pos = 0; |
140 | struct iwl_priv *priv = (struct iwl_priv *)file->private_data; | 148 | struct iwl_priv *priv = (struct iwl_priv *)file->private_data; |
149 | const size_t bufsz = sizeof(buf); | ||
141 | 150 | ||
142 | printk(KERN_DEBUG "offset is: 0x%x\tlen is: 0x%x\n", | 151 | printk(KERN_DEBUG "offset is: 0x%x\tlen is: 0x%x\n", |
143 | priv->dbgfs->sram_offset, priv->dbgfs->sram_len); | 152 | priv->dbgfs->sram_offset, priv->dbgfs->sram_len); |
@@ -159,9 +168,9 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, | |||
159 | break; | 168 | break; |
160 | } | 169 | } |
161 | } | 170 | } |
162 | pos += sprintf(buf+pos, "0x%08x ", val); | 171 | pos += scnprintf(buf + pos, bufsz - pos, "0x%08x ", val); |
163 | } | 172 | } |
164 | pos += sprintf(buf+pos, "\n"); | 173 | pos += scnprintf(buf + pos, bufsz - pos, "\n"); |
165 | iwl_release_nic_access(priv); | 174 | iwl_release_nic_access(priv); |
166 | 175 | ||
167 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 176 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
@@ -198,7 +207,7 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, | |||
198 | { | 207 | { |
199 | struct iwl_priv *priv = (struct iwl_priv *)file->private_data; | 208 | struct iwl_priv *priv = (struct iwl_priv *)file->private_data; |
200 | struct iwl4965_station_entry *station; | 209 | struct iwl4965_station_entry *station; |
201 | int max_sta = priv->hw_setting.max_stations; | 210 | int max_sta = priv->hw_params.max_stations; |
202 | char *buf; | 211 | char *buf; |
203 | int i, j, pos = 0; | 212 | int i, j, pos = 0; |
204 | ssize_t ret; | 213 | ssize_t ret; |
@@ -210,44 +219,50 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, | |||
210 | if(!buf) | 219 | if(!buf) |
211 | return -ENOMEM; | 220 | return -ENOMEM; |
212 | 221 | ||
213 | pos += sprintf(buf+pos, "num of stations: %d\n\n", | 222 | pos += scnprintf(buf + pos, bufsz - pos, "num of stations: %d\n\n", |
214 | priv->num_stations); | 223 | priv->num_stations); |
215 | 224 | ||
216 | for (i = 0; i < max_sta; i++) { | 225 | for (i = 0; i < max_sta; i++) { |
217 | station = &priv->stations[i]; | 226 | station = &priv->stations[i]; |
218 | if (station->used) { | 227 | if (station->used) { |
219 | pos += sprintf(buf+pos, "station %d:\ngeneral data:\n", | 228 | pos += scnprintf(buf + pos, bufsz - pos, |
220 | i+1); | 229 | "station %d:\ngeneral data:\n", i+1); |
221 | print_mac(mac, station->sta.sta.addr); | 230 | print_mac(mac, station->sta.sta.addr); |
222 | pos += sprintf(buf+pos, "id: %u\n", | 231 | pos += scnprintf(buf + pos, bufsz - pos, "id: %u\n", |
223 | station->sta.sta.sta_id); | 232 | station->sta.sta.sta_id); |
224 | pos += sprintf(buf+pos, "mode: %u\n", | 233 | pos += scnprintf(buf + pos, bufsz - pos, "mode: %u\n", |
225 | station->sta.mode); | 234 | station->sta.mode); |
226 | pos += sprintf(buf+pos, "flags: 0x%x\n", | 235 | pos += scnprintf(buf + pos, bufsz - pos, |
236 | "flags: 0x%x\n", | ||
227 | station->sta.station_flags_msk); | 237 | station->sta.station_flags_msk); |
228 | pos += sprintf(buf+pos, "ps_status: %u\n", | 238 | pos += scnprintf(buf + pos, bufsz - pos, |
229 | station->ps_status); | 239 | "ps_status: %u\n", station->ps_status); |
230 | 240 | pos += scnprintf(buf + pos, bufsz - pos, "tid data:\n"); | |
231 | pos += sprintf(buf+pos, "tid data:\n"); | 241 | pos += scnprintf(buf + pos, bufsz - pos, |
232 | 242 | "seq_num\t\ttxq_id\t"); | |
233 | pos += sprintf(buf+pos, "seq_num\t\ttxq_id\t"); | 243 | pos += scnprintf(buf + pos, bufsz - pos, |
234 | pos += sprintf(buf+pos, "frame_count\twait_for_ba\t"); | 244 | "frame_count\twait_for_ba\t"); |
235 | pos += sprintf(buf+pos, "start_idx\tbitmap0\t"); | 245 | pos += scnprintf(buf + pos, bufsz - pos, |
236 | pos += sprintf(buf+pos, "bitmap1\trate_n_flags\n"); | 246 | "start_idx\tbitmap0\t"); |
247 | pos += scnprintf(buf + pos, bufsz - pos, | ||
248 | "bitmap1\trate_n_flags\n"); | ||
237 | 249 | ||
238 | for (j = 0; j < MAX_TID_COUNT; j++) { | 250 | for (j = 0; j < MAX_TID_COUNT; j++) { |
239 | pos += sprintf(buf+pos, "[%d]:\t\t%u\t", | 251 | pos += scnprintf(buf + pos, bufsz - pos, |
240 | j, station->tid[j].seq_number); | 252 | "[%d]:\t\t%u\t", j, |
241 | pos += sprintf(buf+pos, "%u\t\t%u\t\t%u\t\t", | 253 | station->tid[j].seq_number); |
254 | pos += scnprintf(buf + pos, bufsz - pos, | ||
255 | "%u\t\t%u\t\t%u\t\t", | ||
242 | station->tid[j].agg.txq_id, | 256 | station->tid[j].agg.txq_id, |
243 | station->tid[j].agg.frame_count, | 257 | station->tid[j].agg.frame_count, |
244 | station->tid[j].agg.wait_for_ba); | 258 | station->tid[j].agg.wait_for_ba); |
245 | pos += sprintf(buf+pos, "%u\t%llu\t%u\n", | 259 | pos += scnprintf(buf + pos, bufsz - pos, |
260 | "%u\t%llu\t%u\n", | ||
246 | station->tid[j].agg.start_idx, | 261 | station->tid[j].agg.start_idx, |
247 | (unsigned long long)station->tid[j].agg.bitmap, | 262 | (unsigned long long)station->tid[j].agg.bitmap, |
248 | station->tid[j].agg.rate_n_flags); | 263 | station->tid[j].agg.rate_n_flags); |
249 | } | 264 | } |
250 | pos += sprintf(buf+pos, "\n"); | 265 | pos += scnprintf(buf + pos, bufsz - pos, "\n"); |
251 | } | 266 | } |
252 | } | 267 | } |
253 | 268 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index 1f8c2999805b..fdb27f1cdc08 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c | |||
@@ -51,6 +51,7 @@ const char *get_cmd_string(u8 cmd) | |||
51 | IWL_CMD(REPLY_ADD_STA); | 51 | IWL_CMD(REPLY_ADD_STA); |
52 | IWL_CMD(REPLY_REMOVE_STA); | 52 | IWL_CMD(REPLY_REMOVE_STA); |
53 | IWL_CMD(REPLY_REMOVE_ALL_STA); | 53 | IWL_CMD(REPLY_REMOVE_ALL_STA); |
54 | IWL_CMD(REPLY_WEPKEY); | ||
54 | IWL_CMD(REPLY_TX); | 55 | IWL_CMD(REPLY_TX); |
55 | IWL_CMD(REPLY_RATE_SCALE); | 56 | IWL_CMD(REPLY_RATE_SCALE); |
56 | IWL_CMD(REPLY_LEDS_CMD); | 57 | IWL_CMD(REPLY_LEDS_CMD); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.c b/drivers/net/wireless/iwlwifi/iwl-rfkill.c index 8f38c24491cd..5980a5621cb8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rfkill.c +++ b/drivers/net/wireless/iwlwifi/iwl-rfkill.c | |||
@@ -47,6 +47,9 @@ static int iwl_rfkill_soft_rf_kill(void *data, enum rfkill_state state) | |||
47 | if (!priv->rfkill_mngr.rfkill) | 47 | if (!priv->rfkill_mngr.rfkill) |
48 | return 0; | 48 | return 0; |
49 | 49 | ||
50 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
51 | return 0; | ||
52 | |||
50 | IWL_DEBUG_RF_KILL("we recieved soft RFKILL set to state %d\n", state); | 53 | IWL_DEBUG_RF_KILL("we recieved soft RFKILL set to state %d\n", state); |
51 | mutex_lock(&priv->mutex); | 54 | mutex_lock(&priv->mutex); |
52 | 55 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.h b/drivers/net/wireless/iwlwifi/iwl-rfkill.h index e7aa51a1db18..a7f04b855403 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rfkill.h +++ b/drivers/net/wireless/iwlwifi/iwl-rfkill.h | |||
@@ -34,7 +34,7 @@ struct iwl_priv; | |||
34 | #include <linux/input.h> | 34 | #include <linux/input.h> |
35 | 35 | ||
36 | 36 | ||
37 | #ifdef CONFIG_IWLCORE_RFKILL | 37 | #ifdef CONFIG_IWLWIFI_RFKILL |
38 | struct iwl_rfkill_mngr { | 38 | struct iwl_rfkill_mngr { |
39 | struct rfkill *rfkill; | 39 | struct rfkill *rfkill; |
40 | struct input_dev *input_dev; | 40 | struct input_dev *input_dev; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c new file mode 100644 index 000000000000..e4fdfaa2b9b2 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c | |||
@@ -0,0 +1,355 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved. | ||
4 | * | ||
5 | * Portions of this file are derived from the ipw3945 project, as well | ||
6 | * as portions of the ieee80211 subsystem header files. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of version 2 of the GNU General Public License as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
15 | * more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License along with | ||
18 | * this program; if not, write to the Free Software Foundation, Inc., | ||
19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
20 | * | ||
21 | * The full GNU General Public License is included in this distribution in the | ||
22 | * file called LICENSE. | ||
23 | * | ||
24 | * Contact Information: | ||
25 | * James P. Ketrenos <ipw2100-admin@linux.intel.com> | ||
26 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | |||
30 | #include <net/mac80211.h> | ||
31 | |||
32 | #include "iwl-eeprom.h" | ||
33 | #include "iwl-4965.h" | ||
34 | #include "iwl-core.h" | ||
35 | #include "iwl-sta.h" | ||
36 | #include "iwl-io.h" | ||
37 | #include "iwl-helpers.h" | ||
38 | #include "iwl-4965.h" | ||
39 | #include "iwl-sta.h" | ||
40 | |||
41 | int iwl_get_free_ucode_key_index(struct iwl_priv *priv) | ||
42 | { | ||
43 | int i; | ||
44 | |||
45 | for (i = 0; i < STA_KEY_MAX_NUM; i++) | ||
46 | if (!test_and_set_bit(i, &priv->ucode_key_table)) | ||
47 | return i; | ||
48 | |||
49 | return -1; | ||
50 | } | ||
51 | |||
52 | int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty) | ||
53 | { | ||
54 | int i, not_empty = 0; | ||
55 | u8 buff[sizeof(struct iwl_wep_cmd) + | ||
56 | sizeof(struct iwl_wep_key) * WEP_KEYS_MAX]; | ||
57 | struct iwl_wep_cmd *wep_cmd = (struct iwl_wep_cmd *)buff; | ||
58 | size_t cmd_size = sizeof(struct iwl_wep_cmd); | ||
59 | struct iwl_host_cmd cmd = { | ||
60 | .id = REPLY_WEPKEY, | ||
61 | .data = wep_cmd, | ||
62 | .meta.flags = CMD_ASYNC, | ||
63 | }; | ||
64 | |||
65 | memset(wep_cmd, 0, cmd_size + | ||
66 | (sizeof(struct iwl_wep_key) * WEP_KEYS_MAX)); | ||
67 | |||
68 | for (i = 0; i < WEP_KEYS_MAX ; i++) { | ||
69 | wep_cmd->key[i].key_index = i; | ||
70 | if (priv->wep_keys[i].key_size) { | ||
71 | wep_cmd->key[i].key_offset = i; | ||
72 | not_empty = 1; | ||
73 | } else { | ||
74 | wep_cmd->key[i].key_offset = WEP_INVALID_OFFSET; | ||
75 | } | ||
76 | |||
77 | wep_cmd->key[i].key_size = priv->wep_keys[i].key_size; | ||
78 | memcpy(&wep_cmd->key[i].key[3], priv->wep_keys[i].key, | ||
79 | priv->wep_keys[i].key_size); | ||
80 | } | ||
81 | |||
82 | wep_cmd->global_key_type = WEP_KEY_WEP_TYPE; | ||
83 | wep_cmd->num_keys = WEP_KEYS_MAX; | ||
84 | |||
85 | cmd_size += sizeof(struct iwl_wep_key) * WEP_KEYS_MAX; | ||
86 | |||
87 | cmd.len = cmd_size; | ||
88 | |||
89 | if (not_empty || send_if_empty) | ||
90 | return iwl_send_cmd(priv, &cmd); | ||
91 | else | ||
92 | return 0; | ||
93 | } | ||
94 | |||
95 | int iwl_remove_default_wep_key(struct iwl_priv *priv, | ||
96 | struct ieee80211_key_conf *keyconf) | ||
97 | { | ||
98 | int ret; | ||
99 | unsigned long flags; | ||
100 | |||
101 | spin_lock_irqsave(&priv->sta_lock, flags); | ||
102 | |||
103 | if (!test_and_clear_bit(keyconf->keyidx, &priv->ucode_key_table)) | ||
104 | IWL_ERROR("index %d not used in uCode key table.\n", | ||
105 | keyconf->keyidx); | ||
106 | |||
107 | priv->default_wep_key--; | ||
108 | memset(&priv->wep_keys[keyconf->keyidx], 0, sizeof(priv->wep_keys[0])); | ||
109 | ret = iwl_send_static_wepkey_cmd(priv, 1); | ||
110 | spin_unlock_irqrestore(&priv->sta_lock, flags); | ||
111 | |||
112 | return ret; | ||
113 | } | ||
114 | |||
115 | int iwl_set_default_wep_key(struct iwl_priv *priv, | ||
116 | struct ieee80211_key_conf *keyconf) | ||
117 | { | ||
118 | int ret; | ||
119 | unsigned long flags; | ||
120 | |||
121 | keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV; | ||
122 | keyconf->hw_key_idx = keyconf->keyidx; | ||
123 | priv->stations[IWL_AP_ID].keyinfo.alg = ALG_WEP; | ||
124 | |||
125 | spin_lock_irqsave(&priv->sta_lock, flags); | ||
126 | priv->default_wep_key++; | ||
127 | |||
128 | if (test_and_set_bit(keyconf->keyidx, &priv->ucode_key_table)) | ||
129 | IWL_ERROR("index %d already used in uCode key table.\n", | ||
130 | keyconf->keyidx); | ||
131 | |||
132 | priv->wep_keys[keyconf->keyidx].key_size = keyconf->keylen; | ||
133 | memcpy(&priv->wep_keys[keyconf->keyidx].key, &keyconf->key, | ||
134 | keyconf->keylen); | ||
135 | |||
136 | ret = iwl_send_static_wepkey_cmd(priv, 0); | ||
137 | spin_unlock_irqrestore(&priv->sta_lock, flags); | ||
138 | |||
139 | return ret; | ||
140 | } | ||
141 | |||
142 | static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv, | ||
143 | struct ieee80211_key_conf *keyconf, | ||
144 | u8 sta_id) | ||
145 | { | ||
146 | unsigned long flags; | ||
147 | __le16 key_flags = 0; | ||
148 | int ret; | ||
149 | |||
150 | keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV; | ||
151 | keyconf->hw_key_idx = keyconf->keyidx; | ||
152 | |||
153 | key_flags |= (STA_KEY_FLG_WEP | STA_KEY_FLG_MAP_KEY_MSK); | ||
154 | key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); | ||
155 | key_flags &= ~STA_KEY_FLG_INVALID; | ||
156 | |||
157 | if (keyconf->keylen == WEP_KEY_LEN_128) | ||
158 | key_flags |= STA_KEY_FLG_KEY_SIZE_MSK; | ||
159 | |||
160 | if (sta_id == priv->hw_params.bcast_sta_id) | ||
161 | key_flags |= STA_KEY_MULTICAST_MSK; | ||
162 | |||
163 | spin_lock_irqsave(&priv->sta_lock, flags); | ||
164 | |||
165 | priv->stations[sta_id].keyinfo.alg = keyconf->alg; | ||
166 | priv->stations[sta_id].keyinfo.keylen = keyconf->keylen; | ||
167 | priv->stations[sta_id].keyinfo.keyidx = keyconf->keyidx; | ||
168 | |||
169 | memcpy(priv->stations[sta_id].keyinfo.key, | ||
170 | keyconf->key, keyconf->keylen); | ||
171 | |||
172 | memcpy(&priv->stations[sta_id].sta.key.key[3], | ||
173 | keyconf->key, keyconf->keylen); | ||
174 | |||
175 | priv->stations[sta_id].sta.key.key_offset = | ||
176 | iwl_get_free_ucode_key_index(priv); | ||
177 | priv->stations[sta_id].sta.key.key_flags = key_flags; | ||
178 | |||
179 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; | ||
180 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | ||
181 | |||
182 | ret = iwl4965_send_add_station(priv, | ||
183 | &priv->stations[sta_id].sta, CMD_ASYNC); | ||
184 | |||
185 | spin_unlock_irqrestore(&priv->sta_lock, flags); | ||
186 | |||
187 | return ret; | ||
188 | } | ||
189 | |||
190 | static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv, | ||
191 | struct ieee80211_key_conf *keyconf, | ||
192 | u8 sta_id) | ||
193 | { | ||
194 | unsigned long flags; | ||
195 | __le16 key_flags = 0; | ||
196 | |||
197 | key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK); | ||
198 | key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); | ||
199 | key_flags &= ~STA_KEY_FLG_INVALID; | ||
200 | |||
201 | if (sta_id == priv->hw_params.bcast_sta_id) | ||
202 | key_flags |= STA_KEY_MULTICAST_MSK; | ||
203 | |||
204 | keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; | ||
205 | keyconf->hw_key_idx = keyconf->keyidx; | ||
206 | |||
207 | spin_lock_irqsave(&priv->sta_lock, flags); | ||
208 | priv->stations[sta_id].keyinfo.alg = keyconf->alg; | ||
209 | priv->stations[sta_id].keyinfo.keylen = keyconf->keylen; | ||
210 | |||
211 | memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, | ||
212 | keyconf->keylen); | ||
213 | |||
214 | memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, | ||
215 | keyconf->keylen); | ||
216 | |||
217 | priv->stations[sta_id].sta.key.key_offset = | ||
218 | iwl_get_free_ucode_key_index(priv); | ||
219 | priv->stations[sta_id].sta.key.key_flags = key_flags; | ||
220 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; | ||
221 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | ||
222 | |||
223 | spin_unlock_irqrestore(&priv->sta_lock, flags); | ||
224 | |||
225 | IWL_DEBUG_INFO("hwcrypto: modify ucode station key info\n"); | ||
226 | return iwl4965_send_add_station(priv, | ||
227 | &priv->stations[sta_id].sta, CMD_ASYNC); | ||
228 | } | ||
229 | |||
230 | static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv, | ||
231 | struct ieee80211_key_conf *keyconf, | ||
232 | u8 sta_id) | ||
233 | { | ||
234 | unsigned long flags; | ||
235 | int ret = 0; | ||
236 | |||
237 | keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; | ||
238 | keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; | ||
239 | keyconf->hw_key_idx = keyconf->keyidx; | ||
240 | |||
241 | spin_lock_irqsave(&priv->sta_lock, flags); | ||
242 | |||
243 | priv->stations[sta_id].keyinfo.alg = keyconf->alg; | ||
244 | priv->stations[sta_id].keyinfo.conf = keyconf; | ||
245 | priv->stations[sta_id].keyinfo.keylen = 16; | ||
246 | priv->stations[sta_id].sta.key.key_offset = | ||
247 | iwl_get_free_ucode_key_index(priv); | ||
248 | |||
249 | /* This copy is acutally not needed: we get the key with each TX */ | ||
250 | memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, 16); | ||
251 | |||
252 | memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, 16); | ||
253 | |||
254 | spin_unlock_irqrestore(&priv->sta_lock, flags); | ||
255 | |||
256 | return ret; | ||
257 | } | ||
258 | |||
259 | int iwl_remove_dynamic_key(struct iwl_priv *priv, u8 sta_id) | ||
260 | { | ||
261 | unsigned long flags; | ||
262 | |||
263 | priv->key_mapping_key = 0; | ||
264 | |||
265 | spin_lock_irqsave(&priv->sta_lock, flags); | ||
266 | if (!test_and_clear_bit(priv->stations[sta_id].sta.key.key_offset, | ||
267 | &priv->ucode_key_table)) | ||
268 | IWL_ERROR("index %d not used in uCode key table.\n", | ||
269 | priv->stations[sta_id].sta.key.key_offset); | ||
270 | memset(&priv->stations[sta_id].keyinfo, 0, | ||
271 | sizeof(struct iwl4965_hw_key)); | ||
272 | memset(&priv->stations[sta_id].sta.key, 0, | ||
273 | sizeof(struct iwl4965_keyinfo)); | ||
274 | priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC; | ||
275 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; | ||
276 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | ||
277 | spin_unlock_irqrestore(&priv->sta_lock, flags); | ||
278 | |||
279 | IWL_DEBUG_INFO("hwcrypto: clear ucode station key info\n"); | ||
280 | return iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, 0); | ||
281 | } | ||
282 | |||
283 | int iwl_set_dynamic_key(struct iwl_priv *priv, | ||
284 | struct ieee80211_key_conf *key, u8 sta_id) | ||
285 | { | ||
286 | int ret; | ||
287 | |||
288 | priv->key_mapping_key = 1; | ||
289 | |||
290 | switch (key->alg) { | ||
291 | case ALG_CCMP: | ||
292 | ret = iwl_set_ccmp_dynamic_key_info(priv, key, sta_id); | ||
293 | break; | ||
294 | case ALG_TKIP: | ||
295 | ret = iwl_set_tkip_dynamic_key_info(priv, key, sta_id); | ||
296 | break; | ||
297 | case ALG_WEP: | ||
298 | ret = iwl_set_wep_dynamic_key_info(priv, key, sta_id); | ||
299 | break; | ||
300 | default: | ||
301 | IWL_ERROR("Unknown alg: %s alg = %d\n", __func__, key->alg); | ||
302 | ret = -EINVAL; | ||
303 | } | ||
304 | |||
305 | return ret; | ||
306 | } | ||
307 | |||
308 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
309 | static void iwl_dump_lq_cmd(struct iwl_priv *priv, | ||
310 | struct iwl_link_quality_cmd *lq) | ||
311 | { | ||
312 | int i; | ||
313 | IWL_DEBUG_RATE("lq station id 0x%x\n", lq->sta_id); | ||
314 | IWL_DEBUG_RATE("lq dta 0x%X 0x%X\n", | ||
315 | lq->general_params.single_stream_ant_msk, | ||
316 | lq->general_params.dual_stream_ant_msk); | ||
317 | |||
318 | for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) | ||
319 | IWL_DEBUG_RATE("lq index %d 0x%X\n", | ||
320 | i, lq->rs_table[i].rate_n_flags); | ||
321 | } | ||
322 | #else | ||
323 | static inline void iwl_dump_lq_cmd(struct iwl_priv *priv, | ||
324 | struct iwl_link_quality_cmd *lq) | ||
325 | { | ||
326 | } | ||
327 | #endif | ||
328 | |||
329 | int iwl_send_lq_cmd(struct iwl_priv *priv, | ||
330 | struct iwl_link_quality_cmd *lq, u8 flags) | ||
331 | { | ||
332 | struct iwl_host_cmd cmd = { | ||
333 | .id = REPLY_TX_LINK_QUALITY_CMD, | ||
334 | .len = sizeof(struct iwl_link_quality_cmd), | ||
335 | .meta.flags = flags, | ||
336 | .data = lq, | ||
337 | }; | ||
338 | |||
339 | if ((lq->sta_id == 0xFF) && | ||
340 | (priv->iw_mode == IEEE80211_IF_TYPE_IBSS)) | ||
341 | return -EINVAL; | ||
342 | |||
343 | if (lq->sta_id == 0xFF) | ||
344 | lq->sta_id = IWL_AP_ID; | ||
345 | |||
346 | iwl_dump_lq_cmd(priv,lq); | ||
347 | |||
348 | if (iwl_is_associated(priv) && priv->assoc_station_added && | ||
349 | priv->lq_mngr.lq_ready) | ||
350 | return iwl_send_cmd(priv, &cmd); | ||
351 | |||
352 | return 0; | ||
353 | } | ||
354 | EXPORT_SYMBOL(iwl_send_lq_cmd); | ||
355 | |||
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h new file mode 100644 index 000000000000..44f272ecc827 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-sta.h | |||
@@ -0,0 +1,49 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved. | ||
4 | * | ||
5 | * Portions of this file are derived from the ipw3945 project, as well | ||
6 | * as portions of the ieee80211 subsystem header files. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of version 2 of the GNU General Public License as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
15 | * more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License along with | ||
18 | * this program; if not, write to the Free Software Foundation, Inc., | ||
19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
20 | * | ||
21 | * The full GNU General Public License is included in this distribution in the | ||
22 | * file called LICENSE. | ||
23 | * | ||
24 | * Contact Information: | ||
25 | * James P. Ketrenos <ipw2100-admin@linux.intel.com> | ||
26 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | #ifndef __iwl_sta_h__ | ||
30 | #define __iwl_sta_h__ | ||
31 | |||
32 | #include <net/mac80211.h> | ||
33 | |||
34 | #include "iwl-eeprom.h" | ||
35 | #include "iwl-core.h" | ||
36 | #include "iwl-4965.h" | ||
37 | #include "iwl-io.h" | ||
38 | #include "iwl-helpers.h" | ||
39 | |||
40 | int iwl_get_free_ucode_key_index(struct iwl_priv *priv); | ||
41 | int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty); | ||
42 | int iwl_remove_default_wep_key(struct iwl_priv *priv, | ||
43 | struct ieee80211_key_conf *key); | ||
44 | int iwl_set_default_wep_key(struct iwl_priv *priv, | ||
45 | struct ieee80211_key_conf *key); | ||
46 | int iwl_remove_dynamic_key(struct iwl_priv *priv, u8 sta_id); | ||
47 | int iwl_set_dynamic_key(struct iwl_priv *priv, | ||
48 | struct ieee80211_key_conf *key, u8 sta_id); | ||
49 | #endif /* __iwl_sta_h__ */ | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 29a9ecdcbf35..1a5678fe4224 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -70,7 +70,7 @@ static int iwl3945_param_disable; /* def: 0 = enable radio */ | |||
70 | static int iwl3945_param_antenna; /* def: 0 = both antennas (use diversity) */ | 70 | static int iwl3945_param_antenna; /* def: 0 = both antennas (use diversity) */ |
71 | int iwl3945_param_hwcrypto; /* def: 0 = use software encryption */ | 71 | int iwl3945_param_hwcrypto; /* def: 0 = use software encryption */ |
72 | static int iwl3945_param_qos_enable = 1; /* def: 1 = use quality of service */ | 72 | static int iwl3945_param_qos_enable = 1; /* def: 1 = use quality of service */ |
73 | int iwl3945_param_queues_num = IWL_MAX_NUM_QUEUES; /* def: 8 Tx queues */ | 73 | int iwl3945_param_queues_num = IWL39_MAX_NUM_QUEUES; /* def: 8 Tx queues */ |
74 | 74 | ||
75 | /* | 75 | /* |
76 | * module name, copyright, version, etc. | 76 | * module name, copyright, version, etc. |
@@ -7974,10 +7974,10 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
7974 | iwl3945_hw_ops.hw_scan = NULL; | 7974 | iwl3945_hw_ops.hw_scan = NULL; |
7975 | } | 7975 | } |
7976 | 7976 | ||
7977 | if ((iwl3945_param_queues_num > IWL_MAX_NUM_QUEUES) || | 7977 | if ((iwl3945_param_queues_num > IWL39_MAX_NUM_QUEUES) || |
7978 | (iwl3945_param_queues_num < IWL_MIN_NUM_QUEUES)) { | 7978 | (iwl3945_param_queues_num < IWL_MIN_NUM_QUEUES)) { |
7979 | IWL_ERROR("invalid queues_num, should be between %d and %d\n", | 7979 | IWL_ERROR("invalid queues_num, should be between %d and %d\n", |
7980 | IWL_MIN_NUM_QUEUES, IWL_MAX_NUM_QUEUES); | 7980 | IWL_MIN_NUM_QUEUES, IWL39_MAX_NUM_QUEUES); |
7981 | err = -EINVAL; | 7981 | err = -EINVAL; |
7982 | goto out; | 7982 | goto out; |
7983 | } | 7983 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 06e44dad5f02..d7e2358a213a 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c | |||
@@ -50,6 +50,7 @@ | |||
50 | #include "iwl-core.h" | 50 | #include "iwl-core.h" |
51 | #include "iwl-io.h" | 51 | #include "iwl-io.h" |
52 | #include "iwl-helpers.h" | 52 | #include "iwl-helpers.h" |
53 | #include "iwl-sta.h" | ||
53 | 54 | ||
54 | static int iwl4965_tx_queue_update_write_ptr(struct iwl_priv *priv, | 55 | static int iwl4965_tx_queue_update_write_ptr(struct iwl_priv *priv, |
55 | struct iwl4965_tx_queue *txq); | 56 | struct iwl4965_tx_queue *txq); |
@@ -397,9 +398,9 @@ static u8 iwl4965_remove_station(struct iwl_priv *priv, const u8 *addr, int is_a | |||
397 | if (is_ap) | 398 | if (is_ap) |
398 | index = IWL_AP_ID; | 399 | index = IWL_AP_ID; |
399 | else if (is_broadcast_ether_addr(addr)) | 400 | else if (is_broadcast_ether_addr(addr)) |
400 | index = priv->hw_setting.bcast_sta_id; | 401 | index = priv->hw_params.bcast_sta_id; |
401 | else | 402 | else |
402 | for (i = IWL_STA_ID; i < priv->hw_setting.max_stations; i++) | 403 | for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++) |
403 | if (priv->stations[i].used && | 404 | if (priv->stations[i].used && |
404 | !compare_ether_addr(priv->stations[i].sta.sta.addr, | 405 | !compare_ether_addr(priv->stations[i].sta.sta.addr, |
405 | addr)) { | 406 | addr)) { |
@@ -439,9 +440,9 @@ u8 iwl4965_add_station_flags(struct iwl_priv *priv, const u8 *addr, | |||
439 | if (is_ap) | 440 | if (is_ap) |
440 | index = IWL_AP_ID; | 441 | index = IWL_AP_ID; |
441 | else if (is_broadcast_ether_addr(addr)) | 442 | else if (is_broadcast_ether_addr(addr)) |
442 | index = priv->hw_setting.bcast_sta_id; | 443 | index = priv->hw_params.bcast_sta_id; |
443 | else | 444 | else |
444 | for (i = IWL_STA_ID; i < priv->hw_setting.max_stations; i++) { | 445 | for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++) { |
445 | if (!compare_ether_addr(priv->stations[i].sta.sta.addr, | 446 | if (!compare_ether_addr(priv->stations[i].sta.sta.addr, |
446 | addr)) { | 447 | addr)) { |
447 | index = i; | 448 | index = i; |
@@ -482,7 +483,7 @@ u8 iwl4965_add_station_flags(struct iwl_priv *priv, const u8 *addr, | |||
482 | 483 | ||
483 | #ifdef CONFIG_IWL4965_HT | 484 | #ifdef CONFIG_IWL4965_HT |
484 | /* BCAST station and IBSS stations do not work in HT mode */ | 485 | /* BCAST station and IBSS stations do not work in HT mode */ |
485 | if (index != priv->hw_setting.bcast_sta_id && | 486 | if (index != priv->hw_params.bcast_sta_id && |
486 | priv->iw_mode != IEEE80211_IF_TYPE_IBSS) | 487 | priv->iw_mode != IEEE80211_IF_TYPE_IBSS) |
487 | iwl4965_set_ht_add_station(priv, index, | 488 | iwl4965_set_ht_add_station(priv, index, |
488 | (struct ieee80211_ht_info *) ht_data); | 489 | (struct ieee80211_ht_info *) ht_data); |
@@ -574,11 +575,11 @@ int iwl4965_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
574 | txq->need_update = 1; | 575 | txq->need_update = 1; |
575 | 576 | ||
576 | /* Set up entry in queue's byte count circular buffer */ | 577 | /* Set up entry in queue's byte count circular buffer */ |
577 | ret = iwl4965_tx_queue_update_wr_ptr(priv, txq, 0); | 578 | priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, 0); |
578 | 579 | ||
579 | /* Increment and update queue's write index */ | 580 | /* Increment and update queue's write index */ |
580 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); | 581 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); |
581 | iwl4965_tx_queue_update_write_ptr(priv, txq); | 582 | ret = iwl4965_tx_queue_update_write_ptr(priv, txq); |
582 | 583 | ||
583 | spin_unlock_irqrestore(&priv->hcmd_lock, flags); | 584 | spin_unlock_irqrestore(&priv->hcmd_lock, flags); |
584 | return ret ? ret : idx; | 585 | return ret ? ret : idx; |
@@ -595,13 +596,6 @@ static void iwl4965_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt) | |||
595 | 596 | ||
596 | } | 597 | } |
597 | 598 | ||
598 | int iwl4965_send_statistics_request(struct iwl_priv *priv) | ||
599 | { | ||
600 | u32 flags = 0; | ||
601 | return iwl_send_cmd_pdu(priv, REPLY_STATISTICS_CMD, | ||
602 | sizeof(flags), &flags); | ||
603 | } | ||
604 | |||
605 | /** | 599 | /** |
606 | * iwl4965_rxon_add_station - add station into station table. | 600 | * iwl4965_rxon_add_station - add station into station table. |
607 | * | 601 | * |
@@ -755,60 +749,6 @@ static int iwl4965_full_rxon_required(struct iwl_priv *priv) | |||
755 | return 0; | 749 | return 0; |
756 | } | 750 | } |
757 | 751 | ||
758 | static int iwl4965_send_rxon_assoc(struct iwl_priv *priv) | ||
759 | { | ||
760 | int rc = 0; | ||
761 | struct iwl4965_rx_packet *res = NULL; | ||
762 | struct iwl4965_rxon_assoc_cmd rxon_assoc; | ||
763 | struct iwl_host_cmd cmd = { | ||
764 | .id = REPLY_RXON_ASSOC, | ||
765 | .len = sizeof(rxon_assoc), | ||
766 | .meta.flags = CMD_WANT_SKB, | ||
767 | .data = &rxon_assoc, | ||
768 | }; | ||
769 | const struct iwl4965_rxon_cmd *rxon1 = &priv->staging_rxon; | ||
770 | const struct iwl4965_rxon_cmd *rxon2 = &priv->active_rxon; | ||
771 | |||
772 | if ((rxon1->flags == rxon2->flags) && | ||
773 | (rxon1->filter_flags == rxon2->filter_flags) && | ||
774 | (rxon1->cck_basic_rates == rxon2->cck_basic_rates) && | ||
775 | (rxon1->ofdm_ht_single_stream_basic_rates == | ||
776 | rxon2->ofdm_ht_single_stream_basic_rates) && | ||
777 | (rxon1->ofdm_ht_dual_stream_basic_rates == | ||
778 | rxon2->ofdm_ht_dual_stream_basic_rates) && | ||
779 | (rxon1->rx_chain == rxon2->rx_chain) && | ||
780 | (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) { | ||
781 | IWL_DEBUG_INFO("Using current RXON_ASSOC. Not resending.\n"); | ||
782 | return 0; | ||
783 | } | ||
784 | |||
785 | rxon_assoc.flags = priv->staging_rxon.flags; | ||
786 | rxon_assoc.filter_flags = priv->staging_rxon.filter_flags; | ||
787 | rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates; | ||
788 | rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates; | ||
789 | rxon_assoc.reserved = 0; | ||
790 | rxon_assoc.ofdm_ht_single_stream_basic_rates = | ||
791 | priv->staging_rxon.ofdm_ht_single_stream_basic_rates; | ||
792 | rxon_assoc.ofdm_ht_dual_stream_basic_rates = | ||
793 | priv->staging_rxon.ofdm_ht_dual_stream_basic_rates; | ||
794 | rxon_assoc.rx_chain_select_flags = priv->staging_rxon.rx_chain; | ||
795 | |||
796 | rc = iwl_send_cmd_sync(priv, &cmd); | ||
797 | if (rc) | ||
798 | return rc; | ||
799 | |||
800 | res = (struct iwl4965_rx_packet *)cmd.meta.u.skb->data; | ||
801 | if (res->hdr.flags & IWL_CMD_FAILED_MSK) { | ||
802 | IWL_ERROR("Bad return from REPLY_RXON_ASSOC command\n"); | ||
803 | rc = -EIO; | ||
804 | } | ||
805 | |||
806 | priv->alloc_rxb_skb--; | ||
807 | dev_kfree_skb_any(cmd.meta.u.skb); | ||
808 | |||
809 | return rc; | ||
810 | } | ||
811 | |||
812 | /** | 752 | /** |
813 | * iwl4965_commit_rxon - commit staging_rxon to hardware | 753 | * iwl4965_commit_rxon - commit staging_rxon to hardware |
814 | * | 754 | * |
@@ -840,7 +780,7 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv) | |||
840 | * iwl4965_rxon_assoc_cmd which is used to reconfigure filter | 780 | * iwl4965_rxon_assoc_cmd which is used to reconfigure filter |
841 | * and other flags for the current radio configuration. */ | 781 | * and other flags for the current radio configuration. */ |
842 | if (!iwl4965_full_rxon_required(priv)) { | 782 | if (!iwl4965_full_rxon_required(priv)) { |
843 | rc = iwl4965_send_rxon_assoc(priv); | 783 | rc = iwl_send_rxon_assoc(priv); |
844 | if (rc) { | 784 | if (rc) { |
845 | IWL_ERROR("Error setting RXON_ASSOC " | 785 | IWL_ERROR("Error setting RXON_ASSOC " |
846 | "configuration (%d).\n", rc); | 786 | "configuration (%d).\n", rc); |
@@ -895,7 +835,7 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv) | |||
895 | le16_to_cpu(priv->staging_rxon.channel), | 835 | le16_to_cpu(priv->staging_rxon.channel), |
896 | print_mac(mac, priv->staging_rxon.bssid_addr)); | 836 | print_mac(mac, priv->staging_rxon.bssid_addr)); |
897 | 837 | ||
898 | iwl4965_set_rxon_hwcrypto(priv, priv->cfg->mod_params->hw_crypto); | 838 | iwl4965_set_rxon_hwcrypto(priv, !priv->cfg->mod_params->sw_crypto); |
899 | /* Apply the new configuration */ | 839 | /* Apply the new configuration */ |
900 | rc = iwl_send_cmd_pdu(priv, REPLY_RXON, | 840 | rc = iwl_send_cmd_pdu(priv, REPLY_RXON, |
901 | sizeof(struct iwl4965_rxon_cmd), &priv->staging_rxon); | 841 | sizeof(struct iwl4965_rxon_cmd), &priv->staging_rxon); |
@@ -941,6 +881,9 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv) | |||
941 | return -EIO; | 881 | return -EIO; |
942 | } | 882 | } |
943 | priv->assoc_station_added = 1; | 883 | priv->assoc_station_added = 1; |
884 | if (priv->default_wep_key && | ||
885 | iwl_send_static_wepkey_cmd(priv, 0)) | ||
886 | IWL_ERROR("Could not send WEP static key.\n"); | ||
944 | } | 887 | } |
945 | 888 | ||
946 | return 0; | 889 | return 0; |
@@ -1108,131 +1051,6 @@ int iwl4965_send_add_station(struct iwl_priv *priv, | |||
1108 | return rc; | 1051 | return rc; |
1109 | } | 1052 | } |
1110 | 1053 | ||
1111 | static int iwl4965_set_ccmp_dynamic_key_info(struct iwl_priv *priv, | ||
1112 | struct ieee80211_key_conf *keyconf, | ||
1113 | u8 sta_id) | ||
1114 | { | ||
1115 | unsigned long flags; | ||
1116 | __le16 key_flags = 0; | ||
1117 | |||
1118 | key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK); | ||
1119 | key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); | ||
1120 | |||
1121 | if (sta_id == priv->hw_setting.bcast_sta_id) | ||
1122 | key_flags |= STA_KEY_MULTICAST_MSK; | ||
1123 | |||
1124 | keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; | ||
1125 | keyconf->hw_key_idx = keyconf->keyidx; | ||
1126 | |||
1127 | key_flags &= ~STA_KEY_FLG_INVALID; | ||
1128 | |||
1129 | spin_lock_irqsave(&priv->sta_lock, flags); | ||
1130 | priv->stations[sta_id].keyinfo.alg = keyconf->alg; | ||
1131 | priv->stations[sta_id].keyinfo.keylen = keyconf->keylen; | ||
1132 | |||
1133 | memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, | ||
1134 | keyconf->keylen); | ||
1135 | |||
1136 | memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, | ||
1137 | keyconf->keylen); | ||
1138 | |||
1139 | priv->stations[sta_id].sta.key.key_offset | ||
1140 | = (sta_id % STA_KEY_MAX_NUM);/*FIXME*/ | ||
1141 | priv->stations[sta_id].sta.key.key_flags = key_flags; | ||
1142 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; | ||
1143 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | ||
1144 | |||
1145 | spin_unlock_irqrestore(&priv->sta_lock, flags); | ||
1146 | |||
1147 | IWL_DEBUG_INFO("hwcrypto: modify ucode station key info\n"); | ||
1148 | return iwl4965_send_add_station(priv, | ||
1149 | &priv->stations[sta_id].sta, CMD_ASYNC); | ||
1150 | } | ||
1151 | |||
1152 | static int iwl4965_set_tkip_dynamic_key_info(struct iwl_priv *priv, | ||
1153 | struct ieee80211_key_conf *keyconf, | ||
1154 | u8 sta_id) | ||
1155 | { | ||
1156 | unsigned long flags; | ||
1157 | int ret = 0; | ||
1158 | |||
1159 | keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; | ||
1160 | keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; | ||
1161 | keyconf->hw_key_idx = keyconf->keyidx; | ||
1162 | |||
1163 | spin_lock_irqsave(&priv->sta_lock, flags); | ||
1164 | |||
1165 | priv->stations[sta_id].keyinfo.alg = keyconf->alg; | ||
1166 | priv->stations[sta_id].keyinfo.conf = keyconf; | ||
1167 | priv->stations[sta_id].keyinfo.keylen = 16; | ||
1168 | |||
1169 | /* This copy is acutally not needed: we get the key with each TX */ | ||
1170 | memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, 16); | ||
1171 | |||
1172 | memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, 16); | ||
1173 | |||
1174 | spin_unlock_irqrestore(&priv->sta_lock, flags); | ||
1175 | |||
1176 | return ret; | ||
1177 | } | ||
1178 | |||
1179 | static int iwl4965_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id) | ||
1180 | { | ||
1181 | unsigned long flags; | ||
1182 | |||
1183 | spin_lock_irqsave(&priv->sta_lock, flags); | ||
1184 | memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl4965_hw_key)); | ||
1185 | memset(&priv->stations[sta_id].sta.key, 0, sizeof(struct iwl4965_keyinfo)); | ||
1186 | priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC; | ||
1187 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; | ||
1188 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | ||
1189 | spin_unlock_irqrestore(&priv->sta_lock, flags); | ||
1190 | |||
1191 | IWL_DEBUG_INFO("hwcrypto: clear ucode station key info\n"); | ||
1192 | iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, 0); | ||
1193 | return 0; | ||
1194 | } | ||
1195 | |||
1196 | static int iwl4965_set_dynamic_key(struct iwl_priv *priv, | ||
1197 | struct ieee80211_key_conf *key, u8 sta_id) | ||
1198 | { | ||
1199 | int ret; | ||
1200 | |||
1201 | switch (key->alg) { | ||
1202 | case ALG_CCMP: | ||
1203 | ret = iwl4965_set_ccmp_dynamic_key_info(priv, key, sta_id); | ||
1204 | break; | ||
1205 | case ALG_TKIP: | ||
1206 | ret = iwl4965_set_tkip_dynamic_key_info(priv, key, sta_id); | ||
1207 | break; | ||
1208 | case ALG_WEP: | ||
1209 | ret = -EOPNOTSUPP; | ||
1210 | break; | ||
1211 | default: | ||
1212 | IWL_ERROR("Unknown alg: %s alg = %d\n", __func__, key->alg); | ||
1213 | ret = -EINVAL; | ||
1214 | } | ||
1215 | |||
1216 | return ret; | ||
1217 | } | ||
1218 | |||
1219 | static int iwl4965_remove_static_key(struct iwl_priv *priv) | ||
1220 | { | ||
1221 | int ret = -EOPNOTSUPP; | ||
1222 | |||
1223 | return ret; | ||
1224 | } | ||
1225 | |||
1226 | static int iwl4965_set_static_key(struct iwl_priv *priv, | ||
1227 | struct ieee80211_key_conf *key) | ||
1228 | { | ||
1229 | if (key->alg == ALG_WEP) | ||
1230 | return -EOPNOTSUPP; | ||
1231 | |||
1232 | IWL_ERROR("Static key invalid: alg %d\n", key->alg); | ||
1233 | return -EINVAL; | ||
1234 | } | ||
1235 | |||
1236 | static void iwl4965_clear_free_frames(struct iwl_priv *priv) | 1054 | static void iwl4965_clear_free_frames(struct iwl_priv *priv) |
1237 | { | 1055 | { |
1238 | struct list_head *element; | 1056 | struct list_head *element; |
@@ -1353,13 +1171,13 @@ static int iwl4965_send_beacon_cmd(struct iwl_priv *priv) | |||
1353 | * | 1171 | * |
1354 | ******************************************************************************/ | 1172 | ******************************************************************************/ |
1355 | 1173 | ||
1356 | static void iwl4965_unset_hw_setting(struct iwl_priv *priv) | 1174 | static void iwl4965_unset_hw_params(struct iwl_priv *priv) |
1357 | { | 1175 | { |
1358 | if (priv->hw_setting.shared_virt) | 1176 | if (priv->shared_virt) |
1359 | pci_free_consistent(priv->pci_dev, | 1177 | pci_free_consistent(priv->pci_dev, |
1360 | sizeof(struct iwl4965_shared), | 1178 | sizeof(struct iwl4965_shared), |
1361 | priv->hw_setting.shared_virt, | 1179 | priv->shared_virt, |
1362 | priv->hw_setting.shared_phys); | 1180 | priv->shared_phys); |
1363 | } | 1181 | } |
1364 | 1182 | ||
1365 | /** | 1183 | /** |
@@ -1976,7 +1794,7 @@ static void iwl4965_set_flags_for_phymode(struct iwl_priv *priv, | |||
1976 | | RXON_FLG_CCK_MSK); | 1794 | | RXON_FLG_CCK_MSK); |
1977 | priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; | 1795 | priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; |
1978 | } else { | 1796 | } else { |
1979 | /* Copied from iwl4965_bg_post_associate() */ | 1797 | /* Copied from iwl4965_post_associate() */ |
1980 | if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) | 1798 | if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) |
1981 | priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; | 1799 | priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; |
1982 | else | 1800 | else |
@@ -2115,6 +1933,10 @@ static void iwl4965_build_tx_cmd_hwcrypto(struct iwl_priv *priv, | |||
2115 | int sta_id) | 1933 | int sta_id) |
2116 | { | 1934 | { |
2117 | struct iwl4965_hw_key *keyinfo = &priv->stations[sta_id].keyinfo; | 1935 | struct iwl4965_hw_key *keyinfo = &priv->stations[sta_id].keyinfo; |
1936 | struct iwl_wep_key *wepkey; | ||
1937 | int keyidx = 0; | ||
1938 | |||
1939 | BUG_ON(ctl->key_idx > 3); | ||
2118 | 1940 | ||
2119 | switch (keyinfo->alg) { | 1941 | switch (keyinfo->alg) { |
2120 | case ALG_CCMP: | 1942 | case ALG_CCMP: |
@@ -2133,16 +1955,29 @@ static void iwl4965_build_tx_cmd_hwcrypto(struct iwl_priv *priv, | |||
2133 | break; | 1955 | break; |
2134 | 1956 | ||
2135 | case ALG_WEP: | 1957 | case ALG_WEP: |
2136 | cmd->cmd.tx.sec_ctl = TX_CMD_SEC_WEP | | 1958 | wepkey = &priv->wep_keys[ctl->key_idx]; |
2137 | (ctl->key_idx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT; | 1959 | cmd->cmd.tx.sec_ctl = 0; |
2138 | 1960 | if (priv->default_wep_key) { | |
2139 | if (keyinfo->keylen == 13) | 1961 | /* the WEP key was sent as static */ |
2140 | cmd->cmd.tx.sec_ctl |= TX_CMD_SEC_KEY128; | 1962 | keyidx = ctl->key_idx; |
1963 | memcpy(&cmd->cmd.tx.key[3], wepkey->key, | ||
1964 | wepkey->key_size); | ||
1965 | if (wepkey->key_size == WEP_KEY_LEN_128) | ||
1966 | cmd->cmd.tx.sec_ctl |= TX_CMD_SEC_KEY128; | ||
1967 | } else { | ||
1968 | /* the WEP key was sent as dynamic */ | ||
1969 | keyidx = keyinfo->keyidx; | ||
1970 | memcpy(&cmd->cmd.tx.key[3], keyinfo->key, | ||
1971 | keyinfo->keylen); | ||
1972 | if (keyinfo->keylen == WEP_KEY_LEN_128) | ||
1973 | cmd->cmd.tx.sec_ctl |= TX_CMD_SEC_KEY128; | ||
1974 | } | ||
2141 | 1975 | ||
2142 | memcpy(&cmd->cmd.tx.key[3], keyinfo->key, keyinfo->keylen); | 1976 | cmd->cmd.tx.sec_ctl |= (TX_CMD_SEC_WEP | |
1977 | (keyidx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT); | ||
2143 | 1978 | ||
2144 | IWL_DEBUG_TX("Configuring packet for WEP encryption " | 1979 | IWL_DEBUG_TX("Configuring packet for WEP encryption " |
2145 | "with key %d\n", ctl->key_idx); | 1980 | "with key %d\n", keyidx); |
2146 | break; | 1981 | break; |
2147 | 1982 | ||
2148 | default: | 1983 | default: |
@@ -2240,7 +2075,7 @@ static int iwl4965_get_sta_id(struct iwl_priv *priv, | |||
2240 | /* If this frame is broadcast or management, use broadcast station id */ | 2075 | /* If this frame is broadcast or management, use broadcast station id */ |
2241 | if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) || | 2076 | if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) || |
2242 | is_multicast_ether_addr(hdr->addr1)) | 2077 | is_multicast_ether_addr(hdr->addr1)) |
2243 | return priv->hw_setting.bcast_sta_id; | 2078 | return priv->hw_params.bcast_sta_id; |
2244 | 2079 | ||
2245 | switch (priv->iw_mode) { | 2080 | switch (priv->iw_mode) { |
2246 | 2081 | ||
@@ -2254,7 +2089,7 @@ static int iwl4965_get_sta_id(struct iwl_priv *priv, | |||
2254 | sta_id = iwl4965_hw_find_station(priv, hdr->addr1); | 2089 | sta_id = iwl4965_hw_find_station(priv, hdr->addr1); |
2255 | if (sta_id != IWL_INVALID_STATION) | 2090 | if (sta_id != IWL_INVALID_STATION) |
2256 | return sta_id; | 2091 | return sta_id; |
2257 | return priv->hw_setting.bcast_sta_id; | 2092 | return priv->hw_params.bcast_sta_id; |
2258 | 2093 | ||
2259 | /* If this frame is going out to an IBSS network, find the station, | 2094 | /* If this frame is going out to an IBSS network, find the station, |
2260 | * or create a new station table entry */ | 2095 | * or create a new station table entry */ |
@@ -2274,11 +2109,11 @@ static int iwl4965_get_sta_id(struct iwl_priv *priv, | |||
2274 | "Defaulting to broadcast...\n", | 2109 | "Defaulting to broadcast...\n", |
2275 | print_mac(mac, hdr->addr1)); | 2110 | print_mac(mac, hdr->addr1)); |
2276 | iwl_print_hex_dump(IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr)); | 2111 | iwl_print_hex_dump(IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr)); |
2277 | return priv->hw_setting.bcast_sta_id; | 2112 | return priv->hw_params.bcast_sta_id; |
2278 | 2113 | ||
2279 | default: | 2114 | default: |
2280 | IWL_WARNING("Unknown mode of operation: %d", priv->iw_mode); | 2115 | IWL_WARNING("Unknown mode of operation: %d", priv->iw_mode); |
2281 | return priv->hw_setting.bcast_sta_id; | 2116 | return priv->hw_params.bcast_sta_id; |
2282 | } | 2117 | } |
2283 | } | 2118 | } |
2284 | 2119 | ||
@@ -2425,7 +2260,7 @@ static int iwl4965_tx_skb(struct iwl_priv *priv, | |||
2425 | * of the MAC header (device reads on dword boundaries). | 2260 | * of the MAC header (device reads on dword boundaries). |
2426 | * We'll tell device about this padding later. | 2261 | * We'll tell device about this padding later. |
2427 | */ | 2262 | */ |
2428 | len = priv->hw_setting.tx_cmd_len + | 2263 | len = priv->hw_params.tx_cmd_len + |
2429 | sizeof(struct iwl_cmd_header) + hdr_len; | 2264 | sizeof(struct iwl_cmd_header) + hdr_len; |
2430 | 2265 | ||
2431 | len_org = len; | 2266 | len_org = len; |
@@ -2496,7 +2331,7 @@ static int iwl4965_tx_skb(struct iwl_priv *priv, | |||
2496 | ieee80211_get_hdrlen(fc)); | 2331 | ieee80211_get_hdrlen(fc)); |
2497 | 2332 | ||
2498 | /* Set up entry for this TFD in Tx byte-count array */ | 2333 | /* Set up entry for this TFD in Tx byte-count array */ |
2499 | iwl4965_tx_queue_update_wr_ptr(priv, txq, len); | 2334 | priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, len); |
2500 | 2335 | ||
2501 | /* Tell device the write index *just past* this latest filled TFD */ | 2336 | /* Tell device the write index *just past* this latest filled TFD */ |
2502 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); | 2337 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); |
@@ -2592,7 +2427,8 @@ void iwl4965_radio_kill_sw(struct iwl_priv *priv, int disable_radio) | |||
2592 | CSR_UCODE_SW_BIT_RFKILL); | 2427 | CSR_UCODE_SW_BIT_RFKILL); |
2593 | spin_unlock_irqrestore(&priv->lock, flags); | 2428 | spin_unlock_irqrestore(&priv->lock, flags); |
2594 | /* call the host command only if no hw rf-kill set */ | 2429 | /* call the host command only if no hw rf-kill set */ |
2595 | if (!test_bit(STATUS_RF_KILL_HW, &priv->status)) | 2430 | if (!test_bit(STATUS_RF_KILL_HW, &priv->status) && |
2431 | iwl_is_ready(priv)) | ||
2596 | iwl4965_send_card_state(priv, | 2432 | iwl4965_send_card_state(priv, |
2597 | CARD_STATE_CMD_DISABLE, | 2433 | CARD_STATE_CMD_DISABLE, |
2598 | 0); | 2434 | 0); |
@@ -3852,7 +3688,7 @@ static void iwl4965_rx_allocate(struct iwl_priv *priv) | |||
3852 | 3688 | ||
3853 | /* Alloc a new receive buffer */ | 3689 | /* Alloc a new receive buffer */ |
3854 | rxb->skb = | 3690 | rxb->skb = |
3855 | alloc_skb(priv->hw_setting.rx_buf_size, | 3691 | alloc_skb(priv->hw_params.rx_buf_size, |
3856 | __GFP_NOWARN | GFP_ATOMIC); | 3692 | __GFP_NOWARN | GFP_ATOMIC); |
3857 | if (!rxb->skb) { | 3693 | if (!rxb->skb) { |
3858 | if (net_ratelimit()) | 3694 | if (net_ratelimit()) |
@@ -3869,7 +3705,7 @@ static void iwl4965_rx_allocate(struct iwl_priv *priv) | |||
3869 | /* Get physical address of RB/SKB */ | 3705 | /* Get physical address of RB/SKB */ |
3870 | rxb->dma_addr = | 3706 | rxb->dma_addr = |
3871 | pci_map_single(priv->pci_dev, rxb->skb->data, | 3707 | pci_map_single(priv->pci_dev, rxb->skb->data, |
3872 | priv->hw_setting.rx_buf_size, PCI_DMA_FROMDEVICE); | 3708 | priv->hw_params.rx_buf_size, PCI_DMA_FROMDEVICE); |
3873 | list_add_tail(&rxb->list, &rxq->rx_free); | 3709 | list_add_tail(&rxb->list, &rxq->rx_free); |
3874 | rxq->free_count++; | 3710 | rxq->free_count++; |
3875 | } | 3711 | } |
@@ -3912,7 +3748,7 @@ static void iwl4965_rx_queue_free(struct iwl_priv *priv, struct iwl4965_rx_queue | |||
3912 | if (rxq->pool[i].skb != NULL) { | 3748 | if (rxq->pool[i].skb != NULL) { |
3913 | pci_unmap_single(priv->pci_dev, | 3749 | pci_unmap_single(priv->pci_dev, |
3914 | rxq->pool[i].dma_addr, | 3750 | rxq->pool[i].dma_addr, |
3915 | priv->hw_setting.rx_buf_size, | 3751 | priv->hw_params.rx_buf_size, |
3916 | PCI_DMA_FROMDEVICE); | 3752 | PCI_DMA_FROMDEVICE); |
3917 | dev_kfree_skb(rxq->pool[i].skb); | 3753 | dev_kfree_skb(rxq->pool[i].skb); |
3918 | } | 3754 | } |
@@ -3964,7 +3800,7 @@ void iwl4965_rx_queue_reset(struct iwl_priv *priv, struct iwl4965_rx_queue *rxq) | |||
3964 | if (rxq->pool[i].skb != NULL) { | 3800 | if (rxq->pool[i].skb != NULL) { |
3965 | pci_unmap_single(priv->pci_dev, | 3801 | pci_unmap_single(priv->pci_dev, |
3966 | rxq->pool[i].dma_addr, | 3802 | rxq->pool[i].dma_addr, |
3967 | priv->hw_setting.rx_buf_size, | 3803 | priv->hw_params.rx_buf_size, |
3968 | PCI_DMA_FROMDEVICE); | 3804 | PCI_DMA_FROMDEVICE); |
3969 | priv->alloc_rxb_skb--; | 3805 | priv->alloc_rxb_skb--; |
3970 | dev_kfree_skb(rxq->pool[i].skb); | 3806 | dev_kfree_skb(rxq->pool[i].skb); |
@@ -4099,7 +3935,7 @@ static void iwl4965_rx_handle(struct iwl_priv *priv) | |||
4099 | rxq->queue[i] = NULL; | 3935 | rxq->queue[i] = NULL; |
4100 | 3936 | ||
4101 | pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr, | 3937 | pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr, |
4102 | priv->hw_setting.rx_buf_size, | 3938 | priv->hw_params.rx_buf_size, |
4103 | PCI_DMA_FROMDEVICE); | 3939 | PCI_DMA_FROMDEVICE); |
4104 | pkt = (struct iwl4965_rx_packet *)rxb->skb->data; | 3940 | pkt = (struct iwl4965_rx_packet *)rxb->skb->data; |
4105 | 3941 | ||
@@ -4152,7 +3988,7 @@ static void iwl4965_rx_handle(struct iwl_priv *priv) | |||
4152 | } | 3988 | } |
4153 | 3989 | ||
4154 | pci_unmap_single(priv->pci_dev, rxb->dma_addr, | 3990 | pci_unmap_single(priv->pci_dev, rxb->dma_addr, |
4155 | priv->hw_setting.rx_buf_size, | 3991 | priv->hw_params.rx_buf_size, |
4156 | PCI_DMA_FROMDEVICE); | 3992 | PCI_DMA_FROMDEVICE); |
4157 | spin_lock_irqsave(&rxq->lock, flags); | 3993 | spin_lock_irqsave(&rxq->lock, flags); |
4158 | list_add_tail(&rxb->list, &priv->rxq.rx_used); | 3994 | list_add_tail(&rxb->list, &priv->rxq.rx_used); |
@@ -4305,7 +4141,7 @@ static void iwl4965_dump_nic_error_log(struct iwl_priv *priv) | |||
4305 | 4141 | ||
4306 | base = le32_to_cpu(priv->card_alive.error_event_table_ptr); | 4142 | base = le32_to_cpu(priv->card_alive.error_event_table_ptr); |
4307 | 4143 | ||
4308 | if (!iwl4965_hw_valid_rtc_data_addr(base)) { | 4144 | if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { |
4309 | IWL_ERROR("Not valid error log pointer 0x%08X\n", base); | 4145 | IWL_ERROR("Not valid error log pointer 0x%08X\n", base); |
4310 | return; | 4146 | return; |
4311 | } | 4147 | } |
@@ -4400,7 +4236,7 @@ static void iwl4965_dump_nic_event_log(struct iwl_priv *priv) | |||
4400 | u32 size; /* # entries that we'll print */ | 4236 | u32 size; /* # entries that we'll print */ |
4401 | 4237 | ||
4402 | base = le32_to_cpu(priv->card_alive.log_event_table_ptr); | 4238 | base = le32_to_cpu(priv->card_alive.log_event_table_ptr); |
4403 | if (!iwl4965_hw_valid_rtc_data_addr(base)) { | 4239 | if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { |
4404 | IWL_ERROR("Invalid event log pointer 0x%08X\n", base); | 4240 | IWL_ERROR("Invalid event log pointer 0x%08X\n", base); |
4405 | return; | 4241 | return; |
4406 | } | 4242 | } |
@@ -5175,156 +5011,6 @@ static int iwl4965_verify_ucode(struct iwl_priv *priv) | |||
5175 | return rc; | 5011 | return rc; |
5176 | } | 5012 | } |
5177 | 5013 | ||
5178 | |||
5179 | /* check contents of special bootstrap uCode SRAM */ | ||
5180 | static int iwl4965_verify_bsm(struct iwl_priv *priv) | ||
5181 | { | ||
5182 | __le32 *image = priv->ucode_boot.v_addr; | ||
5183 | u32 len = priv->ucode_boot.len; | ||
5184 | u32 reg; | ||
5185 | u32 val; | ||
5186 | |||
5187 | IWL_DEBUG_INFO("Begin verify bsm\n"); | ||
5188 | |||
5189 | /* verify BSM SRAM contents */ | ||
5190 | val = iwl_read_prph(priv, BSM_WR_DWCOUNT_REG); | ||
5191 | for (reg = BSM_SRAM_LOWER_BOUND; | ||
5192 | reg < BSM_SRAM_LOWER_BOUND + len; | ||
5193 | reg += sizeof(u32), image ++) { | ||
5194 | val = iwl_read_prph(priv, reg); | ||
5195 | if (val != le32_to_cpu(*image)) { | ||
5196 | IWL_ERROR("BSM uCode verification failed at " | ||
5197 | "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n", | ||
5198 | BSM_SRAM_LOWER_BOUND, | ||
5199 | reg - BSM_SRAM_LOWER_BOUND, len, | ||
5200 | val, le32_to_cpu(*image)); | ||
5201 | return -EIO; | ||
5202 | } | ||
5203 | } | ||
5204 | |||
5205 | IWL_DEBUG_INFO("BSM bootstrap uCode image OK\n"); | ||
5206 | |||
5207 | return 0; | ||
5208 | } | ||
5209 | |||
5210 | /** | ||
5211 | * iwl4965_load_bsm - Load bootstrap instructions | ||
5212 | * | ||
5213 | * BSM operation: | ||
5214 | * | ||
5215 | * The Bootstrap State Machine (BSM) stores a short bootstrap uCode program | ||
5216 | * in special SRAM that does not power down during RFKILL. When powering back | ||
5217 | * up after power-saving sleeps (or during initial uCode load), the BSM loads | ||
5218 | * the bootstrap program into the on-board processor, and starts it. | ||
5219 | * | ||
5220 | * The bootstrap program loads (via DMA) instructions and data for a new | ||
5221 | * program from host DRAM locations indicated by the host driver in the | ||
5222 | * BSM_DRAM_* registers. Once the new program is loaded, it starts | ||
5223 | * automatically. | ||
5224 | * | ||
5225 | * When initializing the NIC, the host driver points the BSM to the | ||
5226 | * "initialize" uCode image. This uCode sets up some internal data, then | ||
5227 | * notifies host via "initialize alive" that it is complete. | ||
5228 | * | ||
5229 | * The host then replaces the BSM_DRAM_* pointer values to point to the | ||
5230 | * normal runtime uCode instructions and a backup uCode data cache buffer | ||
5231 | * (filled initially with starting data values for the on-board processor), | ||
5232 | * then triggers the "initialize" uCode to load and launch the runtime uCode, | ||
5233 | * which begins normal operation. | ||
5234 | * | ||
5235 | * When doing a power-save shutdown, runtime uCode saves data SRAM into | ||
5236 | * the backup data cache in DRAM before SRAM is powered down. | ||
5237 | * | ||
5238 | * When powering back up, the BSM loads the bootstrap program. This reloads | ||
5239 | * the runtime uCode instructions and the backup data cache into SRAM, | ||
5240 | * and re-launches the runtime uCode from where it left off. | ||
5241 | */ | ||
5242 | static int iwl4965_load_bsm(struct iwl_priv *priv) | ||
5243 | { | ||
5244 | __le32 *image = priv->ucode_boot.v_addr; | ||
5245 | u32 len = priv->ucode_boot.len; | ||
5246 | dma_addr_t pinst; | ||
5247 | dma_addr_t pdata; | ||
5248 | u32 inst_len; | ||
5249 | u32 data_len; | ||
5250 | int rc; | ||
5251 | int i; | ||
5252 | u32 done; | ||
5253 | u32 reg_offset; | ||
5254 | |||
5255 | IWL_DEBUG_INFO("Begin load bsm\n"); | ||
5256 | |||
5257 | /* make sure bootstrap program is no larger than BSM's SRAM size */ | ||
5258 | if (len > IWL_MAX_BSM_SIZE) | ||
5259 | return -EINVAL; | ||
5260 | |||
5261 | /* Tell bootstrap uCode where to find the "Initialize" uCode | ||
5262 | * in host DRAM ... host DRAM physical address bits 35:4 for 4965. | ||
5263 | * NOTE: iwl4965_initialize_alive_start() will replace these values, | ||
5264 | * after the "initialize" uCode has run, to point to | ||
5265 | * runtime/protocol instructions and backup data cache. */ | ||
5266 | pinst = priv->ucode_init.p_addr >> 4; | ||
5267 | pdata = priv->ucode_init_data.p_addr >> 4; | ||
5268 | inst_len = priv->ucode_init.len; | ||
5269 | data_len = priv->ucode_init_data.len; | ||
5270 | |||
5271 | rc = iwl_grab_nic_access(priv); | ||
5272 | if (rc) | ||
5273 | return rc; | ||
5274 | |||
5275 | iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); | ||
5276 | iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); | ||
5277 | iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len); | ||
5278 | iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len); | ||
5279 | |||
5280 | /* Fill BSM memory with bootstrap instructions */ | ||
5281 | for (reg_offset = BSM_SRAM_LOWER_BOUND; | ||
5282 | reg_offset < BSM_SRAM_LOWER_BOUND + len; | ||
5283 | reg_offset += sizeof(u32), image++) | ||
5284 | _iwl_write_prph(priv, reg_offset, | ||
5285 | le32_to_cpu(*image)); | ||
5286 | |||
5287 | rc = iwl4965_verify_bsm(priv); | ||
5288 | if (rc) { | ||
5289 | iwl_release_nic_access(priv); | ||
5290 | return rc; | ||
5291 | } | ||
5292 | |||
5293 | /* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */ | ||
5294 | iwl_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0); | ||
5295 | iwl_write_prph(priv, BSM_WR_MEM_DST_REG, | ||
5296 | RTC_INST_LOWER_BOUND); | ||
5297 | iwl_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32)); | ||
5298 | |||
5299 | /* Load bootstrap code into instruction SRAM now, | ||
5300 | * to prepare to load "initialize" uCode */ | ||
5301 | iwl_write_prph(priv, BSM_WR_CTRL_REG, | ||
5302 | BSM_WR_CTRL_REG_BIT_START); | ||
5303 | |||
5304 | /* Wait for load of bootstrap uCode to finish */ | ||
5305 | for (i = 0; i < 100; i++) { | ||
5306 | done = iwl_read_prph(priv, BSM_WR_CTRL_REG); | ||
5307 | if (!(done & BSM_WR_CTRL_REG_BIT_START)) | ||
5308 | break; | ||
5309 | udelay(10); | ||
5310 | } | ||
5311 | if (i < 100) | ||
5312 | IWL_DEBUG_INFO("BSM write complete, poll %d iterations\n", i); | ||
5313 | else { | ||
5314 | IWL_ERROR("BSM write did not complete!\n"); | ||
5315 | return -EIO; | ||
5316 | } | ||
5317 | |||
5318 | /* Enable future boot loads whenever power management unit triggers it | ||
5319 | * (e.g. when powering back up after power-save shutdown) */ | ||
5320 | iwl_write_prph(priv, BSM_WR_CTRL_REG, | ||
5321 | BSM_WR_CTRL_REG_BIT_START_EN); | ||
5322 | |||
5323 | iwl_release_nic_access(priv); | ||
5324 | |||
5325 | return 0; | ||
5326 | } | ||
5327 | |||
5328 | static void iwl4965_nic_start(struct iwl_priv *priv) | 5014 | static void iwl4965_nic_start(struct iwl_priv *priv) |
5329 | { | 5015 | { |
5330 | /* Remove all resets to allow NIC to operate */ | 5016 | /* Remove all resets to allow NIC to operate */ |
@@ -5634,7 +5320,7 @@ static void iwl4965_init_alive_start(struct iwl_priv *priv) | |||
5634 | */ | 5320 | */ |
5635 | static void iwl4965_alive_start(struct iwl_priv *priv) | 5321 | static void iwl4965_alive_start(struct iwl_priv *priv) |
5636 | { | 5322 | { |
5637 | int rc = 0; | 5323 | int ret = 0; |
5638 | 5324 | ||
5639 | IWL_DEBUG_INFO("Runtime Alive received.\n"); | 5325 | IWL_DEBUG_INFO("Runtime Alive received.\n"); |
5640 | 5326 | ||
@@ -5657,10 +5343,10 @@ static void iwl4965_alive_start(struct iwl_priv *priv) | |||
5657 | 5343 | ||
5658 | iwlcore_clear_stations_table(priv); | 5344 | iwlcore_clear_stations_table(priv); |
5659 | 5345 | ||
5660 | rc = iwl4965_alive_notify(priv); | 5346 | ret = priv->cfg->ops->lib->alive_notify(priv); |
5661 | if (rc) { | 5347 | if (ret) { |
5662 | IWL_WARNING("Could not complete ALIVE transition [ntf]: %d\n", | 5348 | IWL_WARNING("Could not complete ALIVE transition [ntf]: %d\n", |
5663 | rc); | 5349 | ret); |
5664 | goto restart; | 5350 | goto restart; |
5665 | } | 5351 | } |
5666 | 5352 | ||
@@ -5835,7 +5521,8 @@ static void iwl4965_down(struct iwl_priv *priv) | |||
5835 | 5521 | ||
5836 | static int __iwl4965_up(struct iwl_priv *priv) | 5522 | static int __iwl4965_up(struct iwl_priv *priv) |
5837 | { | 5523 | { |
5838 | int rc, i; | 5524 | int i; |
5525 | int ret; | ||
5839 | 5526 | ||
5840 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { | 5527 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { |
5841 | IWL_WARNING("Exit pending; will not bring the NIC up\n"); | 5528 | IWL_WARNING("Exit pending; will not bring the NIC up\n"); |
@@ -5870,10 +5557,10 @@ static int __iwl4965_up(struct iwl_priv *priv) | |||
5870 | iwl_rfkill_set_hw_state(priv); | 5557 | iwl_rfkill_set_hw_state(priv); |
5871 | iwl_write32(priv, CSR_INT, 0xFFFFFFFF); | 5558 | iwl_write32(priv, CSR_INT, 0xFFFFFFFF); |
5872 | 5559 | ||
5873 | rc = iwl4965_hw_nic_init(priv); | 5560 | ret = priv->cfg->ops->lib->hw_nic_init(priv); |
5874 | if (rc) { | 5561 | if (ret) { |
5875 | IWL_ERROR("Unable to int nic\n"); | 5562 | IWL_ERROR("Unable to init nic\n"); |
5876 | return rc; | 5563 | return ret; |
5877 | } | 5564 | } |
5878 | 5565 | ||
5879 | /* make sure rfkill handshake bits are cleared */ | 5566 | /* make sure rfkill handshake bits are cleared */ |
@@ -5906,10 +5593,10 @@ static int __iwl4965_up(struct iwl_priv *priv) | |||
5906 | /* load bootstrap state machine, | 5593 | /* load bootstrap state machine, |
5907 | * load bootstrap program into processor's memory, | 5594 | * load bootstrap program into processor's memory, |
5908 | * prepare to load the "initialize" uCode */ | 5595 | * prepare to load the "initialize" uCode */ |
5909 | rc = iwl4965_load_bsm(priv); | 5596 | ret = priv->cfg->ops->lib->load_ucode(priv); |
5910 | 5597 | ||
5911 | if (rc) { | 5598 | if (ret) { |
5912 | IWL_ERROR("Unable to set up bootstrap uCode: %d\n", rc); | 5599 | IWL_ERROR("Unable to set up bootstrap uCode: %d\n", ret); |
5913 | continue; | 5600 | continue; |
5914 | } | 5601 | } |
5915 | 5602 | ||
@@ -6146,7 +5833,7 @@ static void iwl4965_bg_request_scan(struct work_struct *data) | |||
6146 | } | 5833 | } |
6147 | 5834 | ||
6148 | scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; | 5835 | scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; |
6149 | scan->tx_cmd.sta_id = priv->hw_setting.bcast_sta_id; | 5836 | scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id; |
6150 | scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; | 5837 | scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; |
6151 | 5838 | ||
6152 | 5839 | ||
@@ -6272,10 +5959,8 @@ static void iwl4965_bg_rx_replenish(struct work_struct *data) | |||
6272 | 5959 | ||
6273 | #define IWL_DELAY_NEXT_SCAN (HZ*2) | 5960 | #define IWL_DELAY_NEXT_SCAN (HZ*2) |
6274 | 5961 | ||
6275 | static void iwl4965_bg_post_associate(struct work_struct *data) | 5962 | static void iwl4965_post_associate(struct iwl_priv *priv) |
6276 | { | 5963 | { |
6277 | struct iwl_priv *priv = container_of(data, struct iwl_priv, | ||
6278 | post_associate.work); | ||
6279 | struct ieee80211_conf *conf = NULL; | 5964 | struct ieee80211_conf *conf = NULL; |
6280 | int ret = 0; | 5965 | int ret = 0; |
6281 | DECLARE_MAC_BUF(mac); | 5966 | DECLARE_MAC_BUF(mac); |
@@ -6293,12 +5978,10 @@ static void iwl4965_bg_post_associate(struct work_struct *data) | |||
6293 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 5978 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
6294 | return; | 5979 | return; |
6295 | 5980 | ||
6296 | mutex_lock(&priv->mutex); | ||
6297 | 5981 | ||
6298 | if (!priv->vif || !priv->is_open) { | 5982 | if (!priv->vif || !priv->is_open) |
6299 | mutex_unlock(&priv->mutex); | ||
6300 | return; | 5983 | return; |
6301 | } | 5984 | |
6302 | iwl4965_scan_cancel_timeout(priv, 200); | 5985 | iwl4965_scan_cancel_timeout(priv, 200); |
6303 | 5986 | ||
6304 | conf = ieee80211_get_hw_conf(priv->hw); | 5987 | conf = ieee80211_get_hw_conf(priv->hw); |
@@ -6382,7 +6065,18 @@ static void iwl4965_bg_post_associate(struct work_struct *data) | |||
6382 | 6065 | ||
6383 | /* we have just associated, don't start scan too early */ | 6066 | /* we have just associated, don't start scan too early */ |
6384 | priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN; | 6067 | priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN; |
6068 | } | ||
6069 | |||
6070 | |||
6071 | static void iwl4965_bg_post_associate(struct work_struct *data) | ||
6072 | { | ||
6073 | struct iwl_priv *priv = container_of(data, struct iwl_priv, | ||
6074 | post_associate.work); | ||
6075 | |||
6076 | mutex_lock(&priv->mutex); | ||
6077 | iwl4965_post_associate(priv); | ||
6385 | mutex_unlock(&priv->mutex); | 6078 | mutex_unlock(&priv->mutex); |
6079 | |||
6386 | } | 6080 | } |
6387 | 6081 | ||
6388 | static void iwl4965_bg_abort_scan(struct work_struct *work) | 6082 | static void iwl4965_bg_abort_scan(struct work_struct *work) |
@@ -7004,6 +6698,10 @@ static void iwl4965_bss_info_changed(struct ieee80211_hw *hw, | |||
7004 | 6698 | ||
7005 | if (changes & BSS_CHANGED_ASSOC) { | 6699 | if (changes & BSS_CHANGED_ASSOC) { |
7006 | IWL_DEBUG_MAC80211("ASSOC %d\n", bss_conf->assoc); | 6700 | IWL_DEBUG_MAC80211("ASSOC %d\n", bss_conf->assoc); |
6701 | /* This should never happen as this function should | ||
6702 | * never be called from interrupt context. */ | ||
6703 | if (WARN_ON_ONCE(in_interrupt())) | ||
6704 | return; | ||
7007 | if (bss_conf->assoc) { | 6705 | if (bss_conf->assoc) { |
7008 | priv->assoc_id = bss_conf->aid; | 6706 | priv->assoc_id = bss_conf->aid; |
7009 | priv->beacon_int = bss_conf->beacon_int; | 6707 | priv->beacon_int = bss_conf->beacon_int; |
@@ -7011,14 +6709,16 @@ static void iwl4965_bss_info_changed(struct ieee80211_hw *hw, | |||
7011 | priv->assoc_capability = bss_conf->assoc_capability; | 6709 | priv->assoc_capability = bss_conf->assoc_capability; |
7012 | priv->next_scan_jiffies = jiffies + | 6710 | priv->next_scan_jiffies = jiffies + |
7013 | IWL_DELAY_NEXT_SCAN_AFTER_ASSOC; | 6711 | IWL_DELAY_NEXT_SCAN_AFTER_ASSOC; |
7014 | queue_work(priv->workqueue, &priv->post_associate.work); | 6712 | mutex_lock(&priv->mutex); |
6713 | iwl4965_post_associate(priv); | ||
6714 | mutex_unlock(&priv->mutex); | ||
7015 | } else { | 6715 | } else { |
7016 | priv->assoc_id = 0; | 6716 | priv->assoc_id = 0; |
7017 | IWL_DEBUG_MAC80211("DISASSOC %d\n", bss_conf->assoc); | 6717 | IWL_DEBUG_MAC80211("DISASSOC %d\n", bss_conf->assoc); |
7018 | } | 6718 | } |
7019 | } else if (changes && iwl_is_associated(priv) && priv->assoc_id) { | 6719 | } else if (changes && iwl_is_associated(priv) && priv->assoc_id) { |
7020 | IWL_DEBUG_MAC80211("Associated Changes %d\n", changes); | 6720 | IWL_DEBUG_MAC80211("Associated Changes %d\n", changes); |
7021 | iwl4965_send_rxon_assoc(priv); | 6721 | iwl_send_rxon_assoc(priv); |
7022 | } | 6722 | } |
7023 | 6723 | ||
7024 | } | 6724 | } |
@@ -7106,13 +6806,11 @@ static void iwl4965_mac_update_tkip_key(struct ieee80211_hw *hw, | |||
7106 | key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); | 6806 | key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); |
7107 | key_flags &= ~STA_KEY_FLG_INVALID; | 6807 | key_flags &= ~STA_KEY_FLG_INVALID; |
7108 | 6808 | ||
7109 | if (sta_id == priv->hw_setting.bcast_sta_id) | 6809 | if (sta_id == priv->hw_params.bcast_sta_id) |
7110 | key_flags |= STA_KEY_MULTICAST_MSK; | 6810 | key_flags |= STA_KEY_MULTICAST_MSK; |
7111 | 6811 | ||
7112 | spin_lock_irqsave(&priv->sta_lock, flags); | 6812 | spin_lock_irqsave(&priv->sta_lock, flags); |
7113 | 6813 | ||
7114 | priv->stations[sta_id].sta.key.key_offset = | ||
7115 | (sta_id % STA_KEY_MAX_NUM);/* FIXME */ | ||
7116 | priv->stations[sta_id].sta.key.key_flags = key_flags; | 6814 | priv->stations[sta_id].sta.key.key_flags = key_flags; |
7117 | priv->stations[sta_id].sta.key.tkip_rx_tsc_byte2 = (u8) iv32; | 6815 | priv->stations[sta_id].sta.key.tkip_rx_tsc_byte2 = (u8) iv32; |
7118 | 6816 | ||
@@ -7138,11 +6836,11 @@ static int iwl4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
7138 | DECLARE_MAC_BUF(mac); | 6836 | DECLARE_MAC_BUF(mac); |
7139 | int ret = 0; | 6837 | int ret = 0; |
7140 | u8 sta_id = IWL_INVALID_STATION; | 6838 | u8 sta_id = IWL_INVALID_STATION; |
7141 | u8 static_key; | 6839 | u8 is_default_wep_key = 0; |
7142 | 6840 | ||
7143 | IWL_DEBUG_MAC80211("enter\n"); | 6841 | IWL_DEBUG_MAC80211("enter\n"); |
7144 | 6842 | ||
7145 | if (!priv->cfg->mod_params->hw_crypto) { | 6843 | if (priv->cfg->mod_params->sw_crypto) { |
7146 | IWL_DEBUG_MAC80211("leave - hwcrypto disabled\n"); | 6844 | IWL_DEBUG_MAC80211("leave - hwcrypto disabled\n"); |
7147 | return -EOPNOTSUPP; | 6845 | return -EOPNOTSUPP; |
7148 | } | 6846 | } |
@@ -7151,35 +6849,44 @@ static int iwl4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
7151 | /* only support pairwise keys */ | 6849 | /* only support pairwise keys */ |
7152 | return -EOPNOTSUPP; | 6850 | return -EOPNOTSUPP; |
7153 | 6851 | ||
7154 | /* FIXME: need to differenciate between static and dynamic key | 6852 | sta_id = iwl4965_hw_find_station(priv, addr); |
7155 | * in the level of mac80211 */ | 6853 | if (sta_id == IWL_INVALID_STATION) { |
7156 | static_key = !iwl_is_associated(priv); | 6854 | IWL_DEBUG_MAC80211("leave - %s not in station map.\n", |
6855 | print_mac(mac, addr)); | ||
6856 | return -EINVAL; | ||
7157 | 6857 | ||
7158 | if (!static_key) { | ||
7159 | sta_id = iwl4965_hw_find_station(priv, addr); | ||
7160 | if (sta_id == IWL_INVALID_STATION) { | ||
7161 | IWL_DEBUG_MAC80211("leave - %s not in station map.\n", | ||
7162 | print_mac(mac, addr)); | ||
7163 | return -EINVAL; | ||
7164 | } | ||
7165 | } | 6858 | } |
7166 | 6859 | ||
6860 | mutex_lock(&priv->mutex); | ||
7167 | iwl4965_scan_cancel_timeout(priv, 100); | 6861 | iwl4965_scan_cancel_timeout(priv, 100); |
6862 | mutex_unlock(&priv->mutex); | ||
6863 | |||
6864 | /* If we are getting WEP group key and we didn't receive any key mapping | ||
6865 | * so far, we are in legacy wep mode (group key only), otherwise we are | ||
6866 | * in 1X mode. | ||
6867 | * In legacy wep mode, we use another host command to the uCode */ | ||
6868 | if (key->alg == ALG_WEP && sta_id == priv->hw_params.bcast_sta_id && | ||
6869 | priv->iw_mode != IEEE80211_IF_TYPE_AP) { | ||
6870 | if (cmd == SET_KEY) | ||
6871 | is_default_wep_key = !priv->key_mapping_key; | ||
6872 | else | ||
6873 | is_default_wep_key = priv->default_wep_key; | ||
6874 | } | ||
7168 | 6875 | ||
7169 | switch (cmd) { | 6876 | switch (cmd) { |
7170 | case SET_KEY: | 6877 | case SET_KEY: |
7171 | if (static_key) | 6878 | if (is_default_wep_key) |
7172 | ret = iwl4965_set_static_key(priv, key); | 6879 | ret = iwl_set_default_wep_key(priv, key); |
7173 | else | 6880 | else |
7174 | ret = iwl4965_set_dynamic_key(priv, key, sta_id); | 6881 | ret = iwl_set_dynamic_key(priv, key, sta_id); |
7175 | 6882 | ||
7176 | IWL_DEBUG_MAC80211("enable hwcrypto key\n"); | 6883 | IWL_DEBUG_MAC80211("enable hwcrypto key\n"); |
7177 | break; | 6884 | break; |
7178 | case DISABLE_KEY: | 6885 | case DISABLE_KEY: |
7179 | if (static_key) | 6886 | if (is_default_wep_key) |
7180 | ret = iwl4965_remove_static_key(priv); | 6887 | ret = iwl_remove_default_wep_key(priv, key); |
7181 | else | 6888 | else |
7182 | ret = iwl4965_clear_sta_key_info(priv, sta_id); | 6889 | ret = iwl_remove_dynamic_key(priv, sta_id); |
7183 | 6890 | ||
7184 | IWL_DEBUG_MAC80211("disable hwcrypto key\n"); | 6891 | IWL_DEBUG_MAC80211("disable hwcrypto key\n"); |
7185 | break; | 6892 | break; |
@@ -7776,7 +7483,7 @@ static ssize_t show_statistics(struct device *d, | |||
7776 | return -EAGAIN; | 7483 | return -EAGAIN; |
7777 | 7484 | ||
7778 | mutex_lock(&priv->mutex); | 7485 | mutex_lock(&priv->mutex); |
7779 | rc = iwl4965_send_statistics_request(priv); | 7486 | rc = iwl_send_statistics_request(priv, 0); |
7780 | mutex_unlock(&priv->mutex); | 7487 | mutex_unlock(&priv->mutex); |
7781 | 7488 | ||
7782 | if (rc) { | 7489 | if (rc) { |
@@ -8084,8 +7791,8 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8084 | * 5. Setup HW constants | 7791 | * 5. Setup HW constants |
8085 | ************************/ | 7792 | ************************/ |
8086 | /* Device-specific setup */ | 7793 | /* Device-specific setup */ |
8087 | if (iwl4965_hw_set_hw_setting(priv)) { | 7794 | if (priv->cfg->ops->lib->set_hw_params(priv)) { |
8088 | IWL_ERROR("failed to set hw settings\n"); | 7795 | IWL_ERROR("failed to set hw parameters\n"); |
8089 | goto out_iounmap; | 7796 | goto out_iounmap; |
8090 | } | 7797 | } |
8091 | 7798 | ||
@@ -8095,7 +7802,7 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8095 | 7802 | ||
8096 | err = iwl_setup(priv); | 7803 | err = iwl_setup(priv); |
8097 | if (err) | 7804 | if (err) |
8098 | goto out_unset_hw_settings; | 7805 | goto out_unset_hw_params; |
8099 | /* At this point both hw and priv are initialized. */ | 7806 | /* At this point both hw and priv are initialized. */ |
8100 | 7807 | ||
8101 | /********************************** | 7808 | /********************************** |
@@ -8121,7 +7828,7 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8121 | err = sysfs_create_group(&pdev->dev.kobj, &iwl4965_attribute_group); | 7828 | err = sysfs_create_group(&pdev->dev.kobj, &iwl4965_attribute_group); |
8122 | if (err) { | 7829 | if (err) { |
8123 | IWL_ERROR("failed to create sysfs device attributes\n"); | 7830 | IWL_ERROR("failed to create sysfs device attributes\n"); |
8124 | goto out_unset_hw_settings; | 7831 | goto out_unset_hw_params; |
8125 | } | 7832 | } |
8126 | 7833 | ||
8127 | err = iwl_dbgfs_register(priv, DRV_NAME); | 7834 | err = iwl_dbgfs_register(priv, DRV_NAME); |
@@ -8145,8 +7852,8 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8145 | 7852 | ||
8146 | out_remove_sysfs: | 7853 | out_remove_sysfs: |
8147 | sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group); | 7854 | sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group); |
8148 | out_unset_hw_settings: | 7855 | out_unset_hw_params: |
8149 | iwl4965_unset_hw_setting(priv); | 7856 | iwl4965_unset_hw_params(priv); |
8150 | out_iounmap: | 7857 | out_iounmap: |
8151 | pci_iounmap(pdev, priv->hw_base); | 7858 | pci_iounmap(pdev, priv->hw_base); |
8152 | out_pci_release_regions: | 7859 | out_pci_release_regions: |
@@ -8208,7 +7915,7 @@ static void __devexit iwl4965_pci_remove(struct pci_dev *pdev) | |||
8208 | iwl4965_rx_queue_free(priv, &priv->rxq); | 7915 | iwl4965_rx_queue_free(priv, &priv->rxq); |
8209 | iwl4965_hw_txq_ctx_free(priv); | 7916 | iwl4965_hw_txq_ctx_free(priv); |
8210 | 7917 | ||
8211 | iwl4965_unset_hw_setting(priv); | 7918 | iwl4965_unset_hw_params(priv); |
8212 | iwlcore_clear_stations_table(priv); | 7919 | iwlcore_clear_stations_table(priv); |
8213 | 7920 | ||
8214 | 7921 | ||
@@ -8273,9 +7980,17 @@ static int iwl4965_pci_resume(struct pci_dev *pdev) | |||
8273 | * | 7980 | * |
8274 | *****************************************************************************/ | 7981 | *****************************************************************************/ |
8275 | 7982 | ||
8276 | static struct pci_driver iwl4965_driver = { | 7983 | /* Hardware specific file defines the PCI IDs table for that hardware module */ |
7984 | static struct pci_device_id iwl_hw_card_ids[] = { | ||
7985 | {IWL_PCI_DEVICE(0x4229, PCI_ANY_ID, iwl4965_agn_cfg)}, | ||
7986 | {IWL_PCI_DEVICE(0x4230, PCI_ANY_ID, iwl4965_agn_cfg)}, | ||
7987 | {0} | ||
7988 | }; | ||
7989 | MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids); | ||
7990 | |||
7991 | static struct pci_driver iwl_driver = { | ||
8277 | .name = DRV_NAME, | 7992 | .name = DRV_NAME, |
8278 | .id_table = iwl4965_hw_card_ids, | 7993 | .id_table = iwl_hw_card_ids, |
8279 | .probe = iwl4965_pci_probe, | 7994 | .probe = iwl4965_pci_probe, |
8280 | .remove = __devexit_p(iwl4965_pci_remove), | 7995 | .remove = __devexit_p(iwl4965_pci_remove), |
8281 | #ifdef CONFIG_PM | 7996 | #ifdef CONFIG_PM |
@@ -8297,13 +8012,13 @@ static int __init iwl4965_init(void) | |||
8297 | return ret; | 8012 | return ret; |
8298 | } | 8013 | } |
8299 | 8014 | ||
8300 | ret = pci_register_driver(&iwl4965_driver); | 8015 | ret = pci_register_driver(&iwl_driver); |
8301 | if (ret) { | 8016 | if (ret) { |
8302 | IWL_ERROR("Unable to initialize PCI module\n"); | 8017 | IWL_ERROR("Unable to initialize PCI module\n"); |
8303 | goto error_register; | 8018 | goto error_register; |
8304 | } | 8019 | } |
8305 | #ifdef CONFIG_IWLWIFI_DEBUG | 8020 | #ifdef CONFIG_IWLWIFI_DEBUG |
8306 | ret = driver_create_file(&iwl4965_driver.driver, &driver_attr_debug_level); | 8021 | ret = driver_create_file(&iwl_driver.driver, &driver_attr_debug_level); |
8307 | if (ret) { | 8022 | if (ret) { |
8308 | IWL_ERROR("Unable to create driver sysfs file\n"); | 8023 | IWL_ERROR("Unable to create driver sysfs file\n"); |
8309 | goto error_debug; | 8024 | goto error_debug; |
@@ -8314,7 +8029,7 @@ static int __init iwl4965_init(void) | |||
8314 | 8029 | ||
8315 | #ifdef CONFIG_IWLWIFI_DEBUG | 8030 | #ifdef CONFIG_IWLWIFI_DEBUG |
8316 | error_debug: | 8031 | error_debug: |
8317 | pci_unregister_driver(&iwl4965_driver); | 8032 | pci_unregister_driver(&iwl_driver); |
8318 | #endif | 8033 | #endif |
8319 | error_register: | 8034 | error_register: |
8320 | iwl4965_rate_control_unregister(); | 8035 | iwl4965_rate_control_unregister(); |
@@ -8324,9 +8039,9 @@ error_register: | |||
8324 | static void __exit iwl4965_exit(void) | 8039 | static void __exit iwl4965_exit(void) |
8325 | { | 8040 | { |
8326 | #ifdef CONFIG_IWLWIFI_DEBUG | 8041 | #ifdef CONFIG_IWLWIFI_DEBUG |
8327 | driver_remove_file(&iwl4965_driver.driver, &driver_attr_debug_level); | 8042 | driver_remove_file(&iwl_driver.driver, &driver_attr_debug_level); |
8328 | #endif | 8043 | #endif |
8329 | pci_unregister_driver(&iwl4965_driver); | 8044 | pci_unregister_driver(&iwl_driver); |
8330 | iwl4965_rate_control_unregister(); | 8045 | iwl4965_rate_control_unregister(); |
8331 | } | 8046 | } |
8332 | 8047 | ||