| |   |
| 30 | 30 | ** --------------------------------------------------------------------- |
| 31 | 31 | */ |
| 32 | 32 | |
| 33 | | #include <linux/config.h> |
| 34 | 33 | #include <linux/version.h> |
| 34 | #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18) |
| 35 | #include <linux/config.h> |
| 36 | #endif |
| 35 | 37 | #include <linux/module.h> |
| 36 | 38 | #include <linux/kernel.h> |
| 37 | 39 | #include <linux/sched.h> |
| … | … | |
| 503 | 503 | /* 9 */ "reserved", |
| 504 | 504 | /*10 */ "Cannot support all requested capabilities in Capability Information field", |
| 505 | 505 | /*11 */ "Reassoc denied (reason outside of 802.11b scope)", |
| 506 | | /*12 */ "Assoc denied (reason outside of 802.11b scope), maybe MAC filtering by peer?", |
| 507 | | /*13 */ "Responding station doesnt support specified auth algorithm", |
| 506 | /*12 */ "Assoc denied (reason outside of 802.11b scope) -- maybe MAC filtering by peer?", |
| 507 | /*13 */ "Responding station doesnt support specified auth algorithm -- maybe WEP auth Open vs. Restricted?", |
| 508 | 508 | /*14 */ "Auth rejected: wrong transaction sequence number", |
| 509 | 509 | /*15 */ "Auth rejected: challenge failure", |
| 510 | 510 | /*16 */ "Auth rejected: timeout for next frame in sequence", |
| … | … | |
| 621 | 621 | } |
| 622 | 622 | |
| 623 | 623 | adev->firmware_numver = (u32)( |
| 624 | | (hexarr[0] << 24) + (hexarr[1] << 16) |
| 625 | | + (hexarr[2] << 8) + hexarr[3]); |
| 624 | (hexarr[0] << 24) | (hexarr[1] << 16) |
| 625 | | (hexarr[2] << 8) | hexarr[3]); |
| 626 | 626 | log(L_DEBUG, "firmware_numver 0x%08X\n", adev->firmware_numver); |
| 627 | 627 | } |
| 628 | 628 | if (IS_ACX111(adev)) { |
| … | … | |
| 720 | 720 | break; |
| 721 | 721 | } |
| 722 | 722 | |
| 723 | | printk("acx: form factor 0x%02X (%s), " |
| 724 | | "radio type 0x%02X (%s), EEPROM version 0x%02X, " |
| 725 | | "uploaded firmware '%s' (0x%08X)\n", |
| 726 | | adev->form_factor, form_str, adev->radio_type, radio_str, |
| 727 | | adev->eeprom_version, adev->firmware_version, |
| 728 | | adev->firmware_id); |
| 723 | printk("acx: === chipset %s, radio type 0x%02X (%s), " |
| 724 | "form factor 0x%02X (%s), EEPROM version 0x%02X: " |
| 725 | "uploaded firmware '%s' ===\n", |
| 726 | adev->chip_name, adev->radio_type, radio_str, |
| 727 | adev->form_factor, form_str, adev->eeprom_version, |
| 728 | adev->firmware_version); |
| 729 | 729 | |
| 730 | 730 | FN_EXIT0; |
| 731 | 731 | } |
| … | … | |
| 1205 | 1205 | "** PHY status **\n" |
| 1206 | 1206 | "tx_disabled %d, tx_level_dbm %d\n" /* "tx_level_val %d, tx_level_auto %d\n" */ |
| 1207 | 1207 | "sensitivity %d, antenna 0x%02X, ed_threshold %d, cca %d, preamble_mode %d\n" |
| 1208 | "rate_basic 0x%04X, rate_oper 0x%04X\n" |
| 1208 | 1209 | "rts_threshold %d, frag_threshold %d, short_retry %d, long_retry %d\n" |
| 1209 | 1210 | "msdu_lifetime %d, listen_interval %d, beacon_interval %d\n", |
| 1210 | 1211 | adev->tx_disabled, adev->tx_level_dbm, /* adev->tx_level_val, adev->tx_level_auto, */ |
| 1211 | 1212 | adev->sensitivity, adev->antenna, adev->ed_threshold, adev->cca, adev->preamble_mode, |
| 1213 | adev->rate_basic, adev->rate_oper, |
| 1212 | 1214 | adev->rts_threshold, adev->frag_threshold, adev->short_retry, adev->long_retry, |
| 1213 | 1215 | adev->msdu_lifetime, adev->listen_interval, adev->beacon_interval); |
| 1214 | 1216 | |
| … | … | |
| 4585 | 4585 | |
| 4586 | 4586 | /* People moan about this being too noisy at L_ASSOC */ |
| 4587 | 4587 | log(L_DEBUG, |
| 4588 | | "found %s: ESSID='%s' ch=%d " |
| 4588 | "found %s: ESSID=\"%s\" ch=%d " |
| 4589 | 4589 | "BSSID="MACSTR" caps=0x%04X SIR=%d SNR=%d\n", |
| 4590 | 4590 | (bss->cap_info & WF_MGMT_CAP_IBSS) ? "Ad-Hoc peer" : "AP", |
| 4591 | 4591 | bss->essid, bss->channel, MAC(bss->bssid), bss->cap_info, |
| … | … | |
| 4623 | 4623 | ** other candidates... */ |
| 4624 | 4624 | |
| 4625 | 4625 | printk("%s: association FAILED: peer sent " |
| 4626 | | "response code %d (%s)\n", |
| 4626 | "Status Code %d (%s)\n", |
| 4627 | 4627 | adev->ndev->name, st, get_status_string(st)); |
| 4628 | 4628 | res = NOT_OK; |
| 4629 | 4629 | } |
| … | … | |
| 4702 | 4702 | seq = ieee2host16(*(req->auth_seq)); |
| 4703 | 4703 | status = ieee2host16(*(req->status)); |
| 4704 | 4704 | |
| 4705 | log(L_ASSOC, "auth algorithm %d, auth sequence %d, status %d\n", alg, seq, status); |
| 4706 | |
| 4705 | 4707 | ap = (adev->mode == ACX_MODE_3_AP); |
| 4706 | 4708 | |
| 4707 | 4709 | if (adev->auth_alg <= 1) { |
| … | … | |
| 4714 | 4714 | goto end; |
| 4715 | 4715 | } |
| 4716 | 4716 | } |
| 4717 | | log(L_ASSOC, "algorithm is ok\n"); |
| 4718 | | |
| 4719 | 4717 | if (ap) { |
| 4720 | 4718 | clt = acx_l_sta_list_get_or_add(adev, hdr->a2); |
| 4721 | 4719 | if (STA_LIST_ADD_CAN_FAIL && !clt) { |
| … | … | |
| 4733 | 4733 | |
| 4734 | 4734 | /* now check which step in the authentication sequence we are |
| 4735 | 4735 | * currently in, and act accordingly */ |
| 4736 | | log(L_ASSOC, "acx_process_authen auth seq step %d\n", seq); |
| 4737 | 4736 | switch (seq) { |
| 4738 | 4737 | case 1: |
| 4739 | 4738 | if (!ap) |
| … | … | |
| 4789 | 4789 | acx_l_transmit_assoc_req(adev); |
| 4790 | 4790 | break; |
| 4791 | 4791 | } |
| 4792 | | result = NOT_OK; |
| 4792 | result = OK; |
| 4793 | 4793 | end: |
| 4794 | 4794 | FN_EXIT1(result); |
| 4795 | 4795 | return result; |
| … | … | |
| 4869 | 4869 | |
| 4870 | 4870 | FN_ENTER; |
| 4871 | 4871 | |
| 4872 | | log(L_ASSOC, "sending authentication1 request, " |
| 4873 | | "awaiting response\n"); |
| 4872 | log(L_ASSOC, "sending authentication1 request (auth algo %d), " |
| 4873 | "awaiting response\n", adev->auth_alg); |
| 4874 | 4874 | |
| 4875 | 4875 | tx = acx_l_alloc_tx(adev); |
| 4876 | 4876 | if (!tx) |
| … | … | |
| 4883 | 4883 | body = (void*)(head + 1); |
| 4884 | 4884 | |
| 4885 | 4885 | head->fc = WF_FSTYPE_AUTHENi; |
| 4886 | | head->dur = host2ieee16(0x8000); |
| 4886 | /* duration should be 0 instead of 0x8000 to have |
| 4887 | * the firmware calculate the value, right? */ |
| 4888 | head->dur = 0; |
| 4887 | 4889 | MAC_COPY(head->da, adev->bssid); |
| 4888 | 4890 | MAC_COPY(head->sa, adev->dev_addr); |
| 4889 | 4891 | MAC_COPY(head->bssid, adev->bssid); |
| … | … | |
| 4941 | 4941 | body = (void*)(head + 1); |
| 4942 | 4942 | |
| 4943 | 4943 | head->fc = WF_FSTYPE_AUTHENi; |
| 4944 | | head->dur = req->hdr->dur; |
| 4944 | head->dur = 0 /* req->hdr->dur */; |
| 4945 | 4945 | MAC_COPY(head->da, req->hdr->a2); |
| 4946 | 4946 | MAC_COPY(head->sa, adev->dev_addr); |
| 4947 | 4947 | MAC_COPY(head->bssid, req->hdr->a3); |
| 4948 | | head->seq = req->hdr->seq; |
| 4948 | head->seq = 0 /* req->hdr->seq */; |
| 4949 | 4949 | |
| 4950 | 4950 | /* already in IEEE format, no endianness conversion */ |
| 4951 | 4951 | body->auth_alg = *(req->auth_alg); |
| … | … | |
| 4997 | 4997 | } |
| 4998 | 4998 | body = (void*)(head + 1); |
| 4999 | 4999 | |
| 5000 | /* add WF_FC_ISWEPi: auth step 3 needs to be encrypted */ |
| 5000 | 5001 | head->fc = WF_FC_ISWEPi + WF_FSTYPE_AUTHENi; |
| 5001 | 5002 | /* FIXME: is this needed?? authen4 does it... |
| 5003 | * I think it's even wrong since we shouldn't re-use old |
| 5004 | * values but instead let the firmware calculate proper ones |
| 5002 | 5005 | head->dur = req->hdr->dur; |
| 5003 | 5006 | head->seq = req->hdr->seq; |
| 5004 | 5007 | */ |
| … | … | |
| 5048 | 5048 | body = (void*)(head + 1); |
| 5049 | 5049 | |
| 5050 | 5050 | head->fc = WF_FSTYPE_AUTHENi; /* 0xb0 */ |
| 5051 | | head->dur = req->hdr->dur; |
| 5051 | head->dur = 0 /* req->hdr->dur */; |
| 5052 | 5052 | MAC_COPY(head->da, req->hdr->a2); |
| 5053 | 5053 | MAC_COPY(head->sa, adev->dev_addr); |
| 5054 | 5054 | MAC_COPY(head->bssid, req->hdr->a3); |
| 5055 | | head->seq = req->hdr->seq; |
| 5055 | head->seq = 0 /* req->hdr->seq */; |
| 5056 | 5056 | |
| 5057 | 5057 | /* already in IEEE format, no endianness conversion */ |
| 5058 | 5058 | body->auth_alg = *(req->auth_alg); |
| … | … | |
| 5165 | 5165 | /* calculate lengths */ |
| 5166 | 5166 | packet_len = WLAN_HDR_A3_LEN + (p - body); |
| 5167 | 5167 | |
| 5168 | | log(L_ASSOC, "association: requesting caps 0x%04X, ESSID '%s'\n", |
| 5168 | log(L_ASSOC, "association: requesting caps 0x%04X, ESSID \"%s\"\n", |
| 5169 | 5169 | cap, adev->essid_for_assoc); |
| 5170 | 5170 | |
| 5171 | 5171 | acx_l_tx_data(adev, tx, packet_len); |
| … | … | |
| 5282 | 5282 | bss = &adev->sta_list[i]; |
| 5283 | 5283 | if (!bss->used) continue; |
| 5284 | 5284 | |
| 5285 | | log(L_ASSOC, "scan table: SSID='%s' CH=%d SIR=%d SNR=%d\n", |
| 5285 | log(L_ASSOC, "scan table: SSID=\"%s\" CH=%d SIR=%d SNR=%d\n", |
| 5286 | 5286 | bss->essid, bss->channel, bss->sir, bss->snr); |
| 5287 | 5287 | |
| 5288 | 5288 | if (!mac_is_bcast(adev->ap)) |
| … | … | |
| 5359 | 5359 | if (bss->channel == adev->channel) |
| 5360 | 5360 | break; |
| 5361 | 5361 | } else |
| 5362 | | if (!bss->essid[0] |
| 5363 | | || ((' ' == bss->essid[0]) && !bss->essid[1]) |
| 5364 | | ) { |
| 5362 | if (is_hidden_essid(bss->essid)) { |
| 5365 | 5363 | /* hmm, station with empty or single-space SSID: |
| 5366 | 5364 | * using hidden SSID broadcast? |
| 5367 | 5365 | */ |
| … | … | |
| 5391 | 5391 | bss = &adev->sta_list[idx_found]; |
| 5392 | 5392 | adev->ap_client = bss; |
| 5393 | 5393 | |
| 5394 | | if (bss->essid[0] == '\0') { |
| 5394 | if (is_hidden_essid(bss->essid)) { |
| 5395 | 5395 | /* if the ESSID of the station we found is empty |
| 5396 | 5396 | * (no broadcast), then use user-configured ESSID |
| 5397 | 5397 | * instead */ |
| … | … | |
| 6383 | 6383 | u8 *paddr; |
| 6384 | 6384 | |
| 6385 | 6385 | paddr = &stationID[4]; |
| 6386 | memcpy(adev->dev_addr, adev->ndev->dev_addr, ETH_ALEN); |
| 6386 | 6387 | for (i = 0; i < ETH_ALEN; i++) { |
| 6387 | 6388 | /* copy the MAC address we obtained when we noticed |
| 6388 | 6389 | * that the ethernet iface's MAC changed |
| … | … | |
| 6791 | 6791 | adev->ndev->name); |
| 6792 | 6792 | adev->recalib_msg_ratelimit++; |
| 6793 | 6793 | if (adev->recalib_msg_ratelimit == 5) |
| 6794 | | printk("disabling above message\n"); |
| 6794 | printk("disabling above message until next recalib\n"); |
| 6795 | 6795 | } |
| 6796 | 6796 | return; |
| 6797 | 6797 | } |
| … | … | |
| 6828 | 6828 | } |
| 6829 | 6829 | } |
| 6830 | 6830 | |
| 6831 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20) |
| 6832 | static void |
| 6833 | acx_e_after_interrupt_task(struct work_struct *work) |
| 6834 | { |
| 6835 | acx_device_t *adev = container_of(work, acx_device_t, after_interrupt_task); |
| 6836 | #else |
| 6831 | 6837 | static void |
| 6832 | 6838 | acx_e_after_interrupt_task(void *data) |
| 6833 | 6839 | { |
| 6834 | 6840 | struct net_device *ndev = (struct net_device*)data; |
| 6835 | 6841 | acx_device_t *adev = ndev2adev(ndev); |
| 6842 | #endif |
| 6836 | 6843 | |
| 6837 | 6844 | FN_ENTER; |
| 6838 | 6845 | |
| … | … | |
| 6954 | 6954 | acx_init_task_scheduler(acx_device_t *adev) |
| 6955 | 6955 | { |
| 6956 | 6956 | /* configure task scheduler */ |
| 6957 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20) |
| 6958 | INIT_WORK(&adev->after_interrupt_task, acx_e_after_interrupt_task); |
| 6959 | #else |
| 6957 | 6960 | INIT_WORK(&adev->after_interrupt_task, acx_e_after_interrupt_task, |
| 6958 | 6961 | adev->ndev); |
| 6962 | #endif |
| 6959 | 6963 | } |
| 6960 | 6964 | |
| 6961 | 6965 | |
| … | … | |
| 6980 | 6980 | SET_BIT(adev->set_mask, SET_TEMPLATES|SET_STA_LIST|GETSET_WEP |
| 6981 | 6981 | |GETSET_TXPOWER|GETSET_ANTENNA|GETSET_ED_THRESH|GETSET_CCA |
| 6982 | 6982 | |GETSET_REG_DOMAIN|GETSET_MODE|GETSET_CHANNEL |
| 6983 | | |GETSET_TX|GETSET_RX); |
| 6983 | |GETSET_TX|GETSET_RX|GETSET_STATION_ID); |
| 6984 | 6984 | |
| 6985 | 6985 | log(L_INIT, "updating initial settings on iface activation\n"); |
| 6986 | 6986 | acx_s_update_card_settings(adev); |
| toggle raw diff |
--- a/common.c
+++ b/common.c
@@ -30,8 +30,10 @@
** ---------------------------------------------------------------------
*/
-#include <linux/config.h>
#include <linux/version.h>
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
+#include <linux/config.h>
+#endif
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
@@ -501,8 +503,8 @@ get_status_string(unsigned int status)
/* 9 */ "reserved",
/*10 */ "Cannot support all requested capabilities in Capability Information field",
/*11 */ "Reassoc denied (reason outside of 802.11b scope)",
- /*12 */ "Assoc denied (reason outside of 802.11b scope), maybe MAC filtering by peer?",
- /*13 */ "Responding station doesnt support specified auth algorithm",
+ /*12 */ "Assoc denied (reason outside of 802.11b scope) -- maybe MAC filtering by peer?",
+ /*13 */ "Responding station doesnt support specified auth algorithm -- maybe WEP auth Open vs. Restricted?",
/*14 */ "Auth rejected: wrong transaction sequence number",
/*15 */ "Auth rejected: challenge failure",
/*16 */ "Auth rejected: timeout for next frame in sequence",
@@ -619,8 +621,8 @@ acx_s_get_firmware_version(acx_device_t *adev)
}
adev->firmware_numver = (u32)(
- (hexarr[0] << 24) + (hexarr[1] << 16)
- + (hexarr[2] << 8) + hexarr[3]);
+ (hexarr[0] << 24) | (hexarr[1] << 16)
+ | (hexarr[2] << 8) | hexarr[3]);
log(L_DEBUG, "firmware_numver 0x%08X\n", adev->firmware_numver);
}
if (IS_ACX111(adev)) {
@@ -718,12 +720,12 @@ acx_display_hardware_details(acx_device_t *adev)
break;
}
- printk("acx: form factor 0x%02X (%s), "
- "radio type 0x%02X (%s), EEPROM version 0x%02X, "
- "uploaded firmware '%s' (0x%08X)\n",
- adev->form_factor, form_str, adev->radio_type, radio_str,
- adev->eeprom_version, adev->firmware_version,
- adev->firmware_id);
+ printk("acx: === chipset %s, radio type 0x%02X (%s), "
+ "form factor 0x%02X (%s), EEPROM version 0x%02X: "
+ "uploaded firmware '%s' ===\n",
+ adev->chip_name, adev->radio_type, radio_str,
+ adev->form_factor, form_str, adev->eeprom_version,
+ adev->firmware_version);
FN_EXIT0;
}
@@ -1203,10 +1205,12 @@ acx_s_proc_diag_output(char *buf, acx_device_t *adev)
"** PHY status **\n"
"tx_disabled %d, tx_level_dbm %d\n" /* "tx_level_val %d, tx_level_auto %d\n" */
"sensitivity %d, antenna 0x%02X, ed_threshold %d, cca %d, preamble_mode %d\n"
+ "rate_basic 0x%04X, rate_oper 0x%04X\n"
"rts_threshold %d, frag_threshold %d, short_retry %d, long_retry %d\n"
"msdu_lifetime %d, listen_interval %d, beacon_interval %d\n",
adev->tx_disabled, adev->tx_level_dbm, /* adev->tx_level_val, adev->tx_level_auto, */
adev->sensitivity, adev->antenna, adev->ed_threshold, adev->cca, adev->preamble_mode,
+ adev->rate_basic, adev->rate_oper,
adev->rts_threshold, adev->frag_threshold, adev->short_retry, adev->long_retry,
adev->msdu_lifetime, adev->listen_interval, adev->beacon_interval);
@@ -4581,7 +4585,7 @@ acx_l_process_probe_response(acx_device_t *adev, wlan_fr_proberesp_t *req,
/* People moan about this being too noisy at L_ASSOC */
log(L_DEBUG,
- "found %s: ESSID='%s' ch=%d "
+ "found %s: ESSID=\"%s\" ch=%d "
"BSSID="MACSTR" caps=0x%04X SIR=%d SNR=%d\n",
(bss->cap_info & WF_MGMT_CAP_IBSS) ? "Ad-Hoc peer" : "AP",
bss->essid, bss->channel, MAC(bss->bssid), bss->cap_info,
@@ -4619,7 +4623,7 @@ acx_l_process_assocresp(acx_device_t *adev, const wlan_fr_assocresp_t *req)
** other candidates... */
printk("%s: association FAILED: peer sent "
- "response code %d (%s)\n",
+ "Status Code %d (%s)\n",
adev->ndev->name, st, get_status_string(st));
res = NOT_OK;
}
@@ -4698,6 +4702,8 @@ acx_l_process_authen(acx_device_t *adev, const wlan_fr_authen_t *req)
seq = ieee2host16(*(req->auth_seq));
status = ieee2host16(*(req->status));
+ log(L_ASSOC, "auth algorithm %d, auth sequence %d, status %d\n", alg, seq, status);
+
ap = (adev->mode == ACX_MODE_3_AP);
if (adev->auth_alg <= 1) {
@@ -4708,8 +4714,6 @@ acx_l_process_authen(acx_device_t *adev, const wlan_fr_authen_t *req)
goto end;
}
}
- log(L_ASSOC, "algorithm is ok\n");
-
if (ap) {
clt = acx_l_sta_list_get_or_add(adev, hdr->a2);
if (STA_LIST_ADD_CAN_FAIL && !clt) {
@@ -4729,7 +4733,6 @@ acx_l_process_authen(acx_device_t *adev, const wlan_fr_authen_t *req)
/* now check which step in the authentication sequence we are
* currently in, and act accordingly */
- log(L_ASSOC, "acx_process_authen auth seq step %d\n", seq);
switch (seq) {
case 1:
if (!ap)
@@ -4786,7 +4789,7 @@ acx_l_process_authen(acx_device_t *adev, const wlan_fr_authen_t *req)
acx_l_transmit_assoc_req(adev);
break;
}
- result = NOT_OK;
+ result = OK;
end:
FN_EXIT1(result);
return result;
@@ -4866,8 +4869,8 @@ acx_l_transmit_authen1(acx_device_t *adev)
FN_ENTER;
- log(L_ASSOC, "sending authentication1 request, "
- "awaiting response\n");
+ log(L_ASSOC, "sending authentication1 request (auth algo %d), "
+ "awaiting response\n", adev->auth_alg);
tx = acx_l_alloc_tx(adev);
if (!tx)
@@ -4880,7 +4883,9 @@ acx_l_transmit_authen1(acx_device_t *adev)
body = (void*)(head + 1);
head->fc = WF_FSTYPE_AUTHENi;
- head->dur = host2ieee16(0x8000);
+ /* duration should be 0 instead of 0x8000 to have
+ * the firmware calculate the value, right? */
+ head->dur = 0;
MAC_COPY(head->da, adev->bssid);
MAC_COPY(head->sa, adev->dev_addr);
MAC_COPY(head->bssid, adev->bssid);
@@ -4936,11 +4941,11 @@ acx_l_transmit_authen2(acx_device_t *adev, const wlan_fr_authen_t *req,
body = (void*)(head + 1);
head->fc = WF_FSTYPE_AUTHENi;
- head->dur = req->hdr->dur;
+ head->dur = 0 /* req->hdr->dur */;
MAC_COPY(head->da, req->hdr->a2);
MAC_COPY(head->sa, adev->dev_addr);
MAC_COPY(head->bssid, req->hdr->a3);
- head->seq = req->hdr->seq;
+ head->seq = 0 /* req->hdr->seq */;
/* already in IEEE format, no endianness conversion */
body->auth_alg = *(req->auth_alg);
@@ -4992,8 +4997,11 @@ acx_l_transmit_authen3(acx_device_t *adev, const wlan_fr_authen_t *req)
}
body = (void*)(head + 1);
+ /* add WF_FC_ISWEPi: auth step 3 needs to be encrypted */
head->fc = WF_FC_ISWEPi + WF_FSTYPE_AUTHENi;
/* FIXME: is this needed?? authen4 does it...
+ * I think it's even wrong since we shouldn't re-use old
+ * values but instead let the firmware calculate proper ones
head->dur = req->hdr->dur;
head->seq = req->hdr->seq;
*/
@@ -5040,11 +5048,11 @@ acx_l_transmit_authen4(acx_device_t *adev, const wlan_fr_authen_t *req)
body = (void*)(head + 1);
head->fc = WF_FSTYPE_AUTHENi; /* 0xb0 */
- head->dur = req->hdr->dur;
+ head->dur = 0 /* req->hdr->dur */;
MAC_COPY(head->da, req->hdr->a2);
MAC_COPY(head->sa, adev->dev_addr);
MAC_COPY(head->bssid, req->hdr->a3);
- head->seq = req->hdr->seq;
+ head->seq = 0 /* req->hdr->seq */;
/* already in IEEE format, no endianness conversion */
body->auth_alg = *(req->auth_alg);
@@ -5157,7 +5165,7 @@ acx_l_transmit_assoc_req(acx_device_t *adev)
/* calculate lengths */
packet_len = WLAN_HDR_A3_LEN + (p - body);
- log(L_ASSOC, "association: requesting caps 0x%04X, ESSID '%s'\n",
+ log(L_ASSOC, "association: requesting caps 0x%04X, ESSID \"%s\"\n",
cap, adev->essid_for_assoc);
acx_l_tx_data(adev, tx, packet_len);
@@ -5274,7 +5282,7 @@ acx_s_complete_scan(acx_device_t *adev)
bss = &adev->sta_list[i];
if (!bss->used) continue;
- log(L_ASSOC, "scan table: SSID='%s' CH=%d SIR=%d SNR=%d\n",
+ log(L_ASSOC, "scan table: SSID=\"%s\" CH=%d SIR=%d SNR=%d\n",
bss->essid, bss->channel, bss->sir, bss->snr);
if (!mac_is_bcast(adev->ap))
@@ -5351,9 +5359,7 @@ acx_s_complete_scan(acx_device_t *adev)
if (bss->channel == adev->channel)
break;
} else
- if (!bss->essid[0]
- || ((' ' == bss->essid[0]) && !bss->essid[1])
- ) {
+ if (is_hidden_essid(bss->essid)) {
/* hmm, station with empty or single-space SSID:
* using hidden SSID broadcast?
*/
@@ -5385,7 +5391,7 @@ acx_s_complete_scan(acx_device_t *adev)
bss = &adev->sta_list[idx_found];
adev->ap_client = bss;
- if (bss->essid[0] == '\0') {
+ if (is_hidden_essid(bss->essid)) {
/* if the ESSID of the station we found is empty
* (no broadcast), then use user-configured ESSID
* instead */
@@ -6377,6 +6383,7 @@ acx_s_update_card_settings(acx_device_t *adev)
u8 *paddr;
paddr = &stationID[4];
+ memcpy(adev->dev_addr, adev->ndev->dev_addr, ETH_ALEN);
for (i = 0; i < ETH_ALEN; i++) {
/* copy the MAC address we obtained when we noticed
* that the ethernet iface's MAC changed
@@ -6784,7 +6791,7 @@ acx_s_after_interrupt_recalib(acx_device_t *adev)
adev->ndev->name);
adev->recalib_msg_ratelimit++;
if (adev->recalib_msg_ratelimit == 5)
- printk("disabling above message\n");
+ printk("disabling above message until next recalib\n");
}
return;
}
@@ -6821,11 +6828,18 @@ acx_s_after_interrupt_recalib(acx_device_t *adev)
}
}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
+static void
+acx_e_after_interrupt_task(struct work_struct *work)
+{
+ acx_device_t *adev = container_of(work, acx_device_t, after_interrupt_task);
+#else
static void
acx_e_after_interrupt_task(void *data)
{
struct net_device *ndev = (struct net_device*)data;
acx_device_t *adev = ndev2adev(ndev);
+#endif
FN_ENTER;
@@ -6940,8 +6954,12 @@ void
acx_init_task_scheduler(acx_device_t *adev)
{
/* configure task scheduler */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
+ INIT_WORK(&adev->after_interrupt_task, acx_e_after_interrupt_task);
+#else
INIT_WORK(&adev->after_interrupt_task, acx_e_after_interrupt_task,
adev->ndev);
+#endif
}
@@ -6962,7 +6980,7 @@ acx_s_start(acx_device_t *adev)
SET_BIT(adev->set_mask, SET_TEMPLATES|SET_STA_LIST|GETSET_WEP
|GETSET_TXPOWER|GETSET_ANTENNA|GETSET_ED_THRESH|GETSET_CCA
|GETSET_REG_DOMAIN|GETSET_MODE|GETSET_CHANNEL
- |GETSET_TX|GETSET_RX);
+ |GETSET_TX|GETSET_RX|GETSET_STATION_ID);
log(L_INIT, "updating initial settings on iface activation\n");
acx_s_update_card_settings(adev); |
| |   |
| 31 | 31 | */ |
| 32 | 32 | #define ACX_PCI 1 |
| 33 | 33 | |
| 34 | | #include <linux/config.h> |
| 35 | 34 | #include <linux/version.h> |
| 35 | #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18) |
| 36 | #include <linux/config.h> |
| 37 | #endif |
| 38 | |
| 39 | /* Linux 2.6.18+ uses <linux/utsrelease.h> */ |
| 40 | #ifndef UTS_RELEASE |
| 41 | #include <linux/utsrelease.h> |
| 42 | #endif |
| 43 | |
| 36 | 44 | #include <linux/compiler.h> /* required for Lx 2.6.8 ?? */ |
| 37 | 45 | #include <linux/kernel.h> |
| 38 | 46 | #include <linux/module.h> |
| … | … | |
| 106 | 106 | /*********************************************************************** |
| 107 | 107 | */ |
| 108 | 108 | static void acxpci_i_tx_timeout(struct net_device *ndev); |
| 109 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) |
| 110 | static irqreturn_t acxpci_i_interrupt(int irq, void *dev_id); |
| 111 | #else |
| 109 | 112 | static irqreturn_t acxpci_i_interrupt(int irq, void *dev_id, struct pt_regs *regs); |
| 113 | #endif |
| 110 | 114 | static void acxpci_i_set_multicast_list(struct net_device *ndev); |
| 111 | 115 | |
| 112 | 116 | static int acxpci_e_open(struct net_device *ndev); |
| … | … | |
| 635 | 635 | |
| 636 | 636 | FN_ENTER; |
| 637 | 637 | |
| 638 | /* print exact chipset and radio ID to make sure people really get a clue on which files exactly they are supposed to provide, |
| 639 | * since firmware loading is the biggest enduser PITA with these chipsets. |
| 640 | * Not printing radio ID in 0xHEX in order to not confuse them into wrong file naming */ |
| 641 | printk( "acx: need to load firmware for acx1%02d chipset with radio ID %02x, please provide via firmware hotplug:\n" |
| 642 | "acx: either one file only (<c>ombined firmware image file, radio-specific) or two files (radio-less base image file *plus* separate <r>adio-specific extension file)\n", |
| 643 | IS_ACX111(adev)*11, adev->radio_type); |
| 644 | |
| 638 | 645 | /* Try combined, then main image */ |
| 639 | 646 | adev->need_radio_fw = 0; |
| 640 | 647 | snprintf(filename, sizeof(filename), "tiacx1%02dc%02X", |
| … | … | |
| 660 | 660 | |
| 661 | 661 | for (try = 1; try <= 5; try++) { |
| 662 | 662 | res = acxpci_s_write_fw(adev, fw_image, 0); |
| 663 | | log(L_DEBUG|L_INIT, "acx_write_fw (main/combined):%d\n", res); |
| 663 | log(L_DEBUG|L_INIT, "acx_write_fw (main/combined): %d\n", res); |
| 664 | 664 | if (OK == res) { |
| 665 | 665 | res = acxpci_s_validate_fw(adev, fw_image, 0); |
| 666 | 666 | log(L_DEBUG|L_INIT, "acx_validate_fw " |
| 667 | | "(main/combined):%d\n", res); |
| 667 | "(main/combined): %d\n", res); |
| 668 | 668 | } |
| 669 | 669 | |
| 670 | 670 | if (OK == res) { |
| … | … | |
| 1533 | 1533 | printk("acx: cannot reserve PCI memory region 2\n"); |
| 1534 | 1534 | goto fail_request_mem_region2; |
| 1535 | 1535 | } |
| 1536 | | mem1 = ioremap(phymem1, mem_region1_size); |
| 1536 | |
| 1537 | /* this used to be ioremap(), but ioremap_nocache() |
| 1538 | * is much less risky, right? (and slower?) |
| 1539 | * FIXME: we may want to go back to cached variant if it's |
| 1540 | * certain that our code really properly handles |
| 1541 | * cached operation (memory barriers, volatile?, ...) |
| 1542 | * (but always keep this comment here regardless!) |
| 1543 | * Possibly make this a driver config setting? */ |
| 1544 | |
| 1545 | mem1 = ioremap_nocache(phymem1, mem_region1_size); |
| 1537 | 1546 | if (!mem1) { |
| 1538 | 1547 | printk("acx: ioremap() FAILED\n"); |
| 1539 | 1548 | goto fail_ioremap1; |
| 1540 | 1549 | } |
| 1541 | | mem2 = ioremap(phymem2, mem_region2_size); |
| 1550 | mem2 = ioremap_nocache(phymem2, mem_region2_size); |
| 1542 | 1551 | if (!mem2) { |
| 1543 | 1552 | printk("acx: ioremap() #2 FAILED\n"); |
| 1544 | 1553 | goto fail_ioremap2; |
| … | … | |
| 1569 | 1569 | ndev = alloc_netdev(sizeof(*adev), "wlan%d", dummy_netdev_init); |
| 1570 | 1570 | /* (NB: memsets to 0 entire area) */ |
| 1571 | 1571 | if (!ndev) { |
| 1572 | | printk("acx: no memory for netdevice structure\n"); |
| 1572 | printk("acx: no memory for netdevice struct\n"); |
| 1573 | 1573 | goto fail_alloc_netdev; |
| 1574 | 1574 | } |
| 1575 | 1575 | |
| … | … | |
| 1647 | 1647 | acx_s_interrogate(adev, &co, ACX111_IE_CONFIG_OPTIONS); |
| 1648 | 1648 | } |
| 1649 | 1649 | |
| 1650 | | //TODO: merge them into one function, they are called just once and are the same for pci & usb |
| 1650 | /* TODO: merge them into one function, they are called just once and are the same for pci & usb */ |
| 1651 | 1651 | if (OK != acxpci_read_eeprom_byte(adev, 0x05, &adev->eeprom_version)) |
| 1652 | 1652 | goto fail_read_eeprom_version; |
| 1653 | 1653 | |
| … | … | |
| 2101 | 2101 | |
| 2102 | 2102 | acx_init_task_scheduler(adev); |
| 2103 | 2103 | |
| 2104 | | //TODO: pci_set_power_state(pdev, PCI_D0); ? |
| 2104 | /* TODO: pci_set_power_state(pdev, PCI_D0); ? */ |
| 2105 | 2105 | |
| 2106 | 2106 | /* request shared IRQ handler */ |
| 2107 | 2107 | if (request_irq(ndev->irq, acxpci_i_interrupt, SA_SHIRQ, ndev->name, ndev)) { |
| … | … | |
| 2160 | 2160 | write_reg16(adev, IO_ACX_FEMR, 0x0); |
| 2161 | 2161 | free_irq(ndev->irq, ndev); |
| 2162 | 2162 | |
| 2163 | | //TODO: pci_set_power_state(pdev, PCI_D3hot); ? |
| 2163 | /* TODO: pci_set_power_state(pdev, PCI_D3hot); ? */ |
| 2164 | 2164 | |
| 2165 | 2165 | /* We currently don't have to do anything else. |
| 2166 | 2166 | * Higher layers know we're not ready from dev->start==0 and |
| … | … | |
| 2461 | 2461 | printk(" Key_Not_Found"); |
| 2462 | 2462 | } |
| 2463 | 2463 | if (irqtype & HOST_INT_IV_ICV_FAILURE) { |
| 2464 | | printk(" IV_ICV_Failure"); |
| 2464 | printk(" IV_ICV_Failure (crypto)"); |
| 2465 | 2465 | } |
| 2466 | 2466 | /* HOST_INT_CMD_COMPLETE */ |
| 2467 | 2467 | /* HOST_INT_INFO */ |
| … | … | |
| 2503 | 2503 | #define MAX_IRQLOOPS_PER_JIFFY (20000/HZ) /* a la orinoco.c */ |
| 2504 | 2504 | |
| 2505 | 2505 | static irqreturn_t |
| 2506 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) |
| 2507 | acxpci_i_interrupt(int irq, void *dev_id) |
| 2508 | #else |
| 2506 | 2509 | acxpci_i_interrupt(int irq, void *dev_id, struct pt_regs *regs) |
| 2510 | #endif |
| 2507 | 2511 | { |
| 2508 | 2512 | acx_device_t *adev; |
| 2509 | 2513 | unsigned long flags; |
| … | … | |
| 3373 | 3373 | adev->stats.tx_fifo_errors++; |
| 3374 | 3374 | break; |
| 3375 | 3375 | case 0x80: |
| 3376 | /* possibly ACPI C-state powersaving related!!! |
| 3377 | * (DMA timeout due to excessively high wakeup |
| 3378 | * latency after C-state activation!?) |
| 3379 | * Disable C-State powersaving and try again, |
| 3380 | * then PLEASE REPORT, I'm VERY interested in |
| 3381 | * whether my theory is correct that this is |
| 3382 | * actually the problem here. |
| 3383 | * In that case, use new Linux idle wakeup latency |
| 3384 | * requirements kernel API to prevent this issue. */ |
| 3376 | 3385 | err = "DMA error"; |
| 3377 | 3386 | adev->wstats.discard.misc++; |
| 3378 | 3387 | break; |
| toggle raw diff |
--- a/pci.c
+++ b/pci.c
@@ -31,8 +31,16 @@
*/
#define ACX_PCI 1
-#include <linux/config.h>
#include <linux/version.h>
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
+#include <linux/config.h>
+#endif
+
+/* Linux 2.6.18+ uses <linux/utsrelease.h> */
+#ifndef UTS_RELEASE
+#include <linux/utsrelease.h>
+#endif
+
#include <linux/compiler.h> /* required for Lx 2.6.8 ?? */
#include <linux/kernel.h>
#include <linux/module.h>
@@ -98,7 +106,11 @@
/***********************************************************************
*/
static void acxpci_i_tx_timeout(struct net_device *ndev);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
+static irqreturn_t acxpci_i_interrupt(int irq, void *dev_id);
+#else
static irqreturn_t acxpci_i_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+#endif
static void acxpci_i_set_multicast_list(struct net_device *ndev);
static int acxpci_e_open(struct net_device *ndev);
@@ -623,6 +635,13 @@ acxpci_s_upload_fw(acx_device_t *adev)
FN_ENTER;
+ /* print exact chipset and radio ID to make sure people really get a clue on which files exactly they are supposed to provide,
+ * since firmware loading is the biggest enduser PITA with these chipsets.
+ * Not printing radio ID in 0xHEX in order to not confuse them into wrong file naming */
+ printk( "acx: need to load firmware for acx1%02d chipset with radio ID %02x, please provide via firmware hotplug:\n"
+ "acx: either one file only (<c>ombined firmware image file, radio-specific) or two files (radio-less base image file *plus* separate <r>adio-specific extension file)\n",
+ IS_ACX111(adev)*11, adev->radio_type);
+
/* Try combined, then main image */
adev->need_radio_fw = 0;
snprintf(filename, sizeof(filename), "tiacx1%02dc%02X",
@@ -641,11 +660,11 @@ acxpci_s_upload_fw(acx_device_t *adev)
for (try = 1; try <= 5; try++) {
res = acxpci_s_write_fw(adev, fw_image, 0);
- log(L_DEBUG|L_INIT, "acx_write_fw (main/combined):%d\n", res);
+ log(L_DEBUG|L_INIT, "acx_write_fw (main/combined): %d\n", res);
if (OK == res) {
res = acxpci_s_validate_fw(adev, fw_image, 0);
log(L_DEBUG|L_INIT, "acx_validate_fw "
- "(main/combined):%d\n", res);
+ "(main/combined): %d\n", res);
}
if (OK == res) {
@@ -1514,12 +1533,21 @@ acxpci_e_probe(struct pci_dev *pdev, const struct pci_device_id *id)
printk("acx: cannot reserve PCI memory region 2\n");
goto fail_request_mem_region2;
}
- mem1 = ioremap(phymem1, mem_region1_size);
+
+ /* this used to be ioremap(), but ioremap_nocache()
+ * is much less risky, right? (and slower?)
+ * FIXME: we may want to go back to cached variant if it's
+ * certain that our code really properly handles
+ * cached operation (memory barriers, volatile?, ...)
+ * (but always keep this comment here regardless!)
+ * Possibly make this a driver config setting? */
+
+ mem1 = ioremap_nocache(phymem1, mem_region1_size);
if (!mem1) {
printk("acx: ioremap() FAILED\n");
goto fail_ioremap1;
}
- mem2 = ioremap(phymem2, mem_region2_size);
+ mem2 = ioremap_nocache(phymem2, mem_region2_size);
if (!mem2) {
printk("acx: ioremap() #2 FAILED\n");
goto fail_ioremap2;
@@ -1541,7 +1569,7 @@ acxpci_e_probe(struct pci_dev *pdev, const struct pci_device_id *id)
ndev = alloc_netdev(sizeof(*adev), "wlan%d", dummy_netdev_init);
/* (NB: memsets to 0 entire area) */
if (!ndev) {
- printk("acx: no memory for netdevice structure\n");
+ printk("acx: no memory for netdevice struct\n");
goto fail_alloc_netdev;
}
@@ -1619,7 +1647,7 @@ acxpci_e_probe(struct pci_dev *pdev, const struct pci_device_id *id)
acx_s_interrogate(adev, &co, ACX111_IE_CONFIG_OPTIONS);
}
-//TODO: merge them into one function, they are called just once and are the same for pci & usb
+/* TODO: merge them into one function, they are called just once and are the same for pci & usb */
if (OK != acxpci_read_eeprom_byte(adev, 0x05, &adev->eeprom_version))
goto fail_read_eeprom_version;
@@ -2073,7 +2101,7 @@ acxpci_e_open(struct net_device *ndev)
acx_init_task_scheduler(adev);
-//TODO: pci_set_power_state(pdev, PCI_D0); ?
+/* TODO: pci_set_power_state(pdev, PCI_D0); ? */
/* request shared IRQ handler */
if (request_irq(ndev->irq, acxpci_i_interrupt, SA_SHIRQ, ndev->name, ndev)) {
@@ -2132,7 +2160,7 @@ acxpci_e_close(struct net_device *ndev)
write_reg16(adev, IO_ACX_FEMR, 0x0);
free_irq(ndev->irq, ndev);
-//TODO: pci_set_power_state(pdev, PCI_D3hot); ?
+/* TODO: pci_set_power_state(pdev, PCI_D3hot); ? */
/* We currently don't have to do anything else.
* Higher layers know we're not ready from dev->start==0 and
@@ -2433,7 +2461,7 @@ log_unusual_irq(u16 irqtype) {
printk(" Key_Not_Found");
}
if (irqtype & HOST_INT_IV_ICV_FAILURE) {
- printk(" IV_ICV_Failure");
+ printk(" IV_ICV_Failure (crypto)");
}
/* HOST_INT_CMD_COMPLETE */
/* HOST_INT_INFO */
@@ -2475,7 +2503,11 @@ update_link_quality_led(acx_device_t *adev)
#define MAX_IRQLOOPS_PER_JIFFY (20000/HZ) /* a la orinoco.c */
static irqreturn_t
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
+acxpci_i_interrupt(int irq, void *dev_id)
+#else
acxpci_i_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+#endif
{
acx_device_t *adev;
unsigned long flags;
@@ -3341,6 +3373,15 @@ handle_tx_error(acx_device_t *adev, u8 error, unsigned int finger)
adev->stats.tx_fifo_errors++;
break;
case 0x80:
+ /* possibly ACPI C-state powersaving related!!!
+ * (DMA timeout due to excessively high wakeup
+ * latency after C-state activation!?)
+ * Disable C-State powersaving and try again,
+ * then PLEASE REPORT, I'm VERY interested in
+ * whether my theory is correct that this is
+ * actually the problem here.
+ * In that case, use new Linux idle wakeup latency
+ * requirements kernel API to prevent this issue. */
err = "DMA error";
adev->wstats.discard.misc++;
break; |