aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorReinette Chatre <reinette.chatre@intel.com>2010-01-22 17:22:48 -0500
committerJohn W. Linville <linville@tuxdriver.com>2010-01-25 16:36:22 -0500
commit1fa97aaeb7fb5111f69abfdb8db656ce19e4951e (patch)
tree193f25f3b7d232ec8040634f89634386e45082f3 /drivers/net/wireless
parent07f33f92e8e1e6ed2ec9d4de048142e7a1d96856 (diff)
iwlwifi: cleanup station adding code
The work done when a station is added is very similar whether the station is added synchronously or asynchronously. Centralize this work. At the same time increase the status flags being checked for when the command returns with accompanying debug messages. Also increase checking when setting the "ucode active" state with accompanying debugging. This work is done in preparation for station notification support. Signed-off-by: Reinette Chatre <reinette.chatre@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c114
1 files changed, 78 insertions, 36 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 8afa39b4b488..842f15653238 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -80,46 +80,103 @@ int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
80} 80}
81EXPORT_SYMBOL(iwl_get_ra_sta_id); 81EXPORT_SYMBOL(iwl_get_ra_sta_id);
82 82
83/* priv->sta_lock must be held */
83static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id) 84static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
84{ 85{
85 unsigned long flags;
86
87 spin_lock_irqsave(&priv->sta_lock, flags);
88 86
89 if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) 87 if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE))
90 IWL_ERR(priv, "ACTIVATE a non DRIVER active station %d\n", 88 IWL_ERR(priv, "ACTIVATE a non DRIVER active station id %u addr %pM\n",
91 sta_id); 89 sta_id, priv->stations[sta_id].sta.sta.addr);
92 90
93 priv->stations[sta_id].used |= IWL_STA_UCODE_ACTIVE; 91 if (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE) {
94 IWL_DEBUG_ASSOC(priv, "Added STA to Ucode: %pM\n", 92 IWL_DEBUG_ASSOC(priv,
95 priv->stations[sta_id].sta.sta.addr); 93 "STA id %u addr %pM already present in uCode (according to driver)\n",
96 94 sta_id, priv->stations[sta_id].sta.sta.addr);
97 spin_unlock_irqrestore(&priv->sta_lock, flags); 95 } else {
96 priv->stations[sta_id].used |= IWL_STA_UCODE_ACTIVE;
97 IWL_DEBUG_ASSOC(priv, "Added STA id %u addr %pM to uCode\n",
98 sta_id, priv->stations[sta_id].sta.sta.addr);
99 }
98} 100}
99 101
100static void iwl_add_sta_callback(struct iwl_priv *priv, 102static void iwl_process_add_sta_resp(struct iwl_priv *priv,
101 struct iwl_device_cmd *cmd, 103 struct iwl_addsta_cmd *addsta,
102 struct iwl_rx_packet *pkt) 104 struct iwl_rx_packet *pkt,
105 bool sync)
103{ 106{
104 struct iwl_addsta_cmd *addsta =
105 (struct iwl_addsta_cmd *)cmd->cmd.payload;
106 u8 sta_id = addsta->sta.sta_id; 107 u8 sta_id = addsta->sta.sta_id;
108 unsigned long flags;
107 109
108 if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { 110 if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
109 IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n", 111 IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n",
110 pkt->hdr.flags); 112 pkt->hdr.flags);
111 return; 113 return;
112 } 114 }
113 115
116 IWL_DEBUG_INFO(priv, "Processing response for adding station %u\n",
117 sta_id);
118
119 spin_lock_irqsave(&priv->sta_lock, flags);
120
114 switch (pkt->u.add_sta.status) { 121 switch (pkt->u.add_sta.status) {
115 case ADD_STA_SUCCESS_MSK: 122 case ADD_STA_SUCCESS_MSK:
123 IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n");
116 iwl_sta_ucode_activate(priv, sta_id); 124 iwl_sta_ucode_activate(priv, sta_id);
117 /* fall through */ 125 break;
126 case ADD_STA_NO_ROOM_IN_TABLE:
127 IWL_ERR(priv, "Adding station %d failed, no room in table.\n",
128 sta_id);
129 break;
130 case ADD_STA_NO_BLOCK_ACK_RESOURCE:
131 IWL_ERR(priv, "Adding station %d failed, no block ack resource.\n",
132 sta_id);
133 break;
134 case ADD_STA_MODIFY_NON_EXIST_STA:
135 IWL_ERR(priv, "Attempting to modify non-existing station %d \n",
136 sta_id);
137 break;
118 default: 138 default:
119 IWL_DEBUG_HC(priv, "Received REPLY_ADD_STA:(0x%08X)\n", 139 IWL_DEBUG_ASSOC(priv, "Received REPLY_ADD_STA:(0x%08X)\n",
120 pkt->u.add_sta.status); 140 pkt->u.add_sta.status);
121 break; 141 break;
122 } 142 }
143
144 IWL_DEBUG_INFO(priv, "%s station id %u addr %pM\n",
145 priv->stations[sta_id].sta.mode ==
146 STA_CONTROL_MODIFY_MSK ? "Modified" : "Added",
147 sta_id, priv->stations[sta_id].sta.sta.addr);
148
149 /*
150 * XXX: The MAC address in the command buffer is often changed from
151 * the original sent to the device. That is, the MAC address
152 * written to the command buffer often is not the same MAC adress
153 * read from the command buffer when the command returns. This
154 * issue has not yet been resolved and this debugging is left to
155 * observe the problem.
156 */
157 IWL_DEBUG_INFO(priv, "%s station according to cmd buffer %pM\n",
158 priv->stations[sta_id].sta.mode ==
159 STA_CONTROL_MODIFY_MSK ? "Modified" : "Added",
160 addsta->sta.addr);
161
162 /*
163 * Determine if we wanted to modify or add a station,
164 * if adding a station succeeded we have some more initialization
165 * to do when using station notification. TODO
166 */
167
168 spin_unlock_irqrestore(&priv->sta_lock, flags);
169}
170
171static void iwl_add_sta_callback(struct iwl_priv *priv,
172 struct iwl_device_cmd *cmd,
173 struct iwl_rx_packet *pkt)
174{
175 struct iwl_addsta_cmd *addsta =
176 (struct iwl_addsta_cmd *)cmd->cmd.payload;
177
178 iwl_process_add_sta_resp(priv, addsta, pkt, false);
179
123} 180}
124 181
125int iwl_send_add_sta(struct iwl_priv *priv, 182int iwl_send_add_sta(struct iwl_priv *priv,
@@ -145,24 +202,9 @@ int iwl_send_add_sta(struct iwl_priv *priv,
145 if (ret || (flags & CMD_ASYNC)) 202 if (ret || (flags & CMD_ASYNC))
146 return ret; 203 return ret;
147 204
148 pkt = (struct iwl_rx_packet *)cmd.reply_page;
149 if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
150 IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n",
151 pkt->hdr.flags);
152 ret = -EIO;
153 }
154
155 if (ret == 0) { 205 if (ret == 0) {
156 switch (pkt->u.add_sta.status) { 206 pkt = (struct iwl_rx_packet *)cmd.reply_page;
157 case ADD_STA_SUCCESS_MSK: 207 iwl_process_add_sta_resp(priv, sta, pkt, true);
158 iwl_sta_ucode_activate(priv, sta->sta.sta_id);
159 IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n");
160 break;
161 default:
162 ret = -EIO;
163 IWL_WARN(priv, "REPLY_ADD_STA failed\n");
164 break;
165 }
166 } 208 }
167 iwl_free_pages(priv, cmd.reply_page); 209 iwl_free_pages(priv, cmd.reply_page);
168 210