Initial commit of the archived acx driver sources (0.2.0pre1)
[acx-mac80211.git] / src / ihw.c
blobdef50811578587fbc7f5849e06bbab705d3da7cd
1 /* src/ihw.c - low level control functions
3 * --------------------------------------------------------------------
5 * Copyright (C) 2003 ACX100 Open Source Project
7 * The contents of this file are subject to the Mozilla Public
8 * License Version 1.1 (the "License"); you may not use this file
9 * except in compliance with the License. You may obtain a copy of
10 * the License at http://www.mozilla.org/MPL/
12 * Software distributed under the License is distributed on an "AS
13 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
14 * implied. See the License for the specific language governing
15 * rights and limitations under the License.
17 * Alternatively, the contents of this file may be used under the
18 * terms of the GNU Public License version 2 (the "GPL"), in which
19 * case the provisions of the GPL are applicable instead of the
20 * above. If you wish to allow the use of your version of this file
21 * only under the terms of the GPL and not to allow others to use
22 * your version of this file under the MPL, indicate your decision
23 * by deleting the provisions above and replace them with the notice
24 * and other provisions required by the GPL. If you do not delete
25 * the provisions above, a recipient may use your version of this
26 * file under either the MPL or the GPL.
28 * --------------------------------------------------------------------
30 * Inquiries regarding the ACX100 Open Source Project can be
31 * made directly to:
33 * acx100-users@lists.sf.net
34 * http://acx100.sf.net
36 * --------------------------------------------------------------------
39 #include <linux/config.h>
40 #define WLAN_DBVAR prism2_debug
41 #include <linux/version.h>
43 #include <linux/module.h>
44 #include <linux/kernel.h>
46 #include <linux/sched.h>
47 #include <linux/types.h>
48 #include <linux/skbuff.h>
49 #include <linux/slab.h>
50 #include <linux/proc_fs.h>
51 #include <linux/if_arp.h>
52 #include <linux/rtnetlink.h>
53 #include <linux/wireless.h>
54 #include <linux/netdevice.h>
55 #include <asm/io.h>
56 #include <linux/delay.h>
57 #include <asm/byteorder.h>
58 #include <asm/bitops.h>
59 #include <asm/uaccess.h>
61 #include <wlan_compat.h>
63 #include <linux/ioport.h>
64 #include <linux/pci.h>
66 #include <asm/pci.h>
67 #include <linux/dcache.h>
68 #include <linux/highmem.h>
69 #include <linux/sched.h>
70 #include <linux/skbuff.h>
71 #include <linux/etherdevice.h>
74 /*================================================================*/
75 /* Project Includes */
77 #include <version.h>
78 #include <p80211hdr.h>
79 #include <p80211mgmt.h>
80 #include <p80211conv.h>
81 #include <p80211msg.h>
82 #include <p80211ioctl.h>
83 #include <acx100.h>
84 #include <p80211netdev.h>
85 #include <p80211req.h>
86 #include <p80211types.h>
87 #include <acx100_helper.h>
88 #include <acx100_helper2.h>
89 #include <idma.h>
90 #include <ihw.h>
91 #include <acx100mgmt.h>
93 /*****************************************************************************
95 * The Really Low Level Stuff (TM)
97 ****************************************************************************/
99 /*----------------------------------------------------------------
100 * hwReadRegister32
101 * rename to acx100_read_reg32
103 * Arguments:
105 * Returns:
107 * Side effects:
109 * Call context:
111 * STATUS:
113 * Comment:
115 *----------------------------------------------------------------*/
117 /* hwReadRegister32()
118 * STATUS: ok
120 UINT32 hwReadRegister32(wlandevice_t * hw, UINT offset)
122 return readl(hw->iobase + offset);
124 /*----------------------------------------------------------------
125 * hwReadRegister16
126 * FIXME: rename to acx100_read_reg16
128 * Arguments:
130 * Returns:
132 * Side effects:
134 * Call context:
136 * STATUS:
138 * Comment:
140 *----------------------------------------------------------------*/
142 /* hwReadRegister16()
143 * STATUS: should be ok.
145 UINT16 hwReadRegister16(wlandevice_t * hw, UINT offset)
147 return readw(hw->iobase + offset);
150 /*----------------------------------------------------------------
151 * hwReadRegister8
152 * FIXME: rename to acx100_read_reg8
154 * Arguments:
156 * Returns:
158 * Side effects:
160 * Call context:
162 * STATUS:
164 * Comment:
166 *----------------------------------------------------------------*/
168 /* hwReadRegister8()
169 * STATUS: ok
171 UINT8 hwReadRegister8(wlandevice_t * hw, UINT offset)
173 return readb(hw->iobase + offset);
176 /*----------------------------------------------------------------
177 * hwWriteRegister32
178 * FIXME: rename to acx100_write_reg32
180 * Arguments:
182 * Returns:
184 * Side effects:
186 * Call context:
188 * STATUS:
190 * Comment:
192 *----------------------------------------------------------------*/
194 /* hwWriteRegister32()
195 * STATUS: should be ok.
197 void hwWriteRegister32(wlandevice_t * hw, UINT offset, UINT valb)
199 writel(valb, hw->iobase + offset);
202 /*----------------------------------------------------------------
203 * hwWriteRegister16
204 * FIXME: rename to acx100_write_reg16
206 * Arguments:
208 * Returns:
210 * Side effects:
212 * Call context:
214 * STATUS:
216 * Comment:
218 *----------------------------------------------------------------*/
220 /* hwWriteRegister16()
221 * STATUS: should be ok.
223 void hwWriteRegister16(wlandevice_t * hw, UINT offset, UINT16 valb)
225 writew(valb, hw->iobase + offset);
228 /*----------------------------------------------------------------
229 * hwWriteRegister8
230 * FIXME: rename to acx100_write_reg8
232 * Arguments:
234 * Returns:
236 * Side effects:
238 * Call context:
240 * STATUS:
242 * Comment:
244 *----------------------------------------------------------------*/
246 /* hwWriteRegister8()
247 * STATUS: should be ok.
249 void hwWriteRegister8(wlandevice_t * hw, UINT offset, UINT valb)
251 writeb(valb, hw->iobase + offset);
254 /*****************************************************************************
256 * Intermediate Level
258 ****************************************************************************/
260 /*----------------------------------------------------------------
261 * get_cmd_state
262 * FIXME: rename to acx100_get_cmd_state
264 * Arguments:
266 * Returns:
268 * Side effects:
270 * Call context:
272 * STATUS:
274 * Comment:
276 *----------------------------------------------------------------*/
278 /* get_cmd_state()
279 * STATUS: wow, lots of errors, but now it should be ok.
281 void get_cmd_state(wlandevice_t * hw)
283 hwWriteRegister16(hw, ACX100_FW_4, 0x0);
284 hwWriteRegister16(hw, ACX100_FW_5, 0x0);
285 hwWriteRegister16(hw, ACX100_FW_2, 0x0);
286 hwWriteRegister16(hw, ACX100_FW_3, 0x1);
287 hwWriteRegister16(hw, ACX100_FW_0,
288 hwReadRegister16(hw, ACX100_CMD_MAILBOX_OFFS));
289 hwWriteRegister16(hw, ACX100_FW_1, 0x0);
290 hw->cmd_type = hwReadRegister16(hw, ACX100_DATA_LO);
291 hw->cmd_status = hwReadRegister16(hw, ACX100_DATA_HI);
293 /*----------------------------------------------------------------
294 * write_cmd_type
295 * FIXME: rename to acx100_write_cmd_type
297 * Arguments:
299 * Returns:
301 * Side effects:
303 * Call context:
305 * STATUS:
307 * Comment:
309 *----------------------------------------------------------------*/
311 /* write_cmd_type()
312 * STATUS: should really be ok.
314 void write_cmd_type(wlandevice_t * hw, UINT16 vala)
316 hwWriteRegister16(hw, ACX100_FW_4, 0x0);
317 hwWriteRegister16(hw, ACX100_FW_5, 0x0);
318 hwWriteRegister16(hw, ACX100_FW_2, 0x0);
319 hwWriteRegister16(hw, ACX100_FW_3, 0x1);
320 hwWriteRegister16(hw, ACX100_FW_0,
321 hwReadRegister16(hw, ACX100_CMD_MAILBOX_OFFS));
322 hwWriteRegister16(hw, ACX100_FW_1, 0x0);
323 hwWriteRegister16(hw, ACX100_DATA_LO, vala);
324 hwWriteRegister16(hw, ACX100_DATA_HI, 0x0);
327 /*----------------------------------------------------------------
328 * write_cmd_status
329 * FIXME: rename to acx100_write_cmd_status
331 * Arguments:
333 * Returns:
335 * Side effects:
337 * Call context:
339 * STATUS:
341 * Comment:
343 *----------------------------------------------------------------*/
345 /* write_cmd_status()
346 * STATUS: should really be ok.
348 void write_cmd_status(wlandevice_t * act, UINT vala)
350 hwWriteRegister16(act, ACX100_FW_4, 0x0);
351 hwWriteRegister16(act, ACX100_FW_5, 0x0);
352 hwWriteRegister16(act, ACX100_FW_2, 0x0);
353 hwWriteRegister16(act, ACX100_FW_3, 0x1);
354 hwWriteRegister16(act, ACX100_FW_0,
355 hwReadRegister16(act, ACX100_CMD_MAILBOX_OFFS));
356 hwWriteRegister16(act, ACX100_FW_1, 0x0);
357 hwWriteRegister16(act, ACX100_DATA_LO, 0x0);
358 hwWriteRegister16(act, ACX100_DATA_HI, vala);
361 /*----------------------------------------------------------------
362 * write_cmd_Parameters
363 * FIXME: rename to acx100_write_cmd_parameters
365 * Arguments:
367 * Returns:
369 * Side effects:
371 * Call context:
373 * STATUS:
375 * Comment:
377 *----------------------------------------------------------------*/
379 /* write_cmd_Parameters()
380 * STATUS: should be ok.
382 int write_cmd_Parameters(wlandevice_t * hw, memmap_t * cmd, int len)
384 memcpy((UINT *) hw->CommandParameters, cmd, len);
385 return 0;
388 /*----------------------------------------------------------------
389 * read_cmd_Parameters
390 * FIXME: rename to acx100_write_cmd_parameters
392 * Arguments:
394 * Returns:
396 * Side effects:
398 * Call context:
400 * STATUS:
402 * Comment:
404 *----------------------------------------------------------------*/
406 /* read_cmd_Parameters()
407 * STATUS: should be ok.
409 int read_cmd_Parameters(wlandevice_t * hw, memmap_t * cmd, int len)
411 memcpy(cmd, (UINT *) hw->CommandParameters, len);
412 return 0;
415 /*----------------------------------------------------------------
416 * ctlIssueCommand
417 * FIXME: rename to acx100_issue_cmd
419 * Arguments:
421 * Returns:
423 * Side effects:
425 * Call context:
427 * STATUS:
429 * Comment:
431 *----------------------------------------------------------------*/
433 /* ctlIssueCommand()
434 * STATUS: FINISHED, UNVERIFIED.
436 int ctlIssueCommand(wlandevice_t * hw, UINT cmd,
437 void *pcmdparam, int paramlen, UINT32 timeout)
439 int counter;
440 int result = 0;
441 UINT16 irqtype = 0;
442 UINT16 cmd_status;
444 FN_ENTER;
445 acxlog(L_CTL, "%s cmd %X timeout %ld: UNVERIFIED.\n", __func__,
446 cmd, timeout);
448 /*** make sure we have at least *some* timeout value ***/
449 if (timeout == 0) {
450 timeout = 1;
454 cmd_state can be one of the following:
455 0x0: IDLE
456 0x1: ??
457 0x2: Unknown Command
458 0x3: INvalid InfoEle
459 0xe: "value out of range"
460 default: Unknown
463 /*** wait for ACX100 to become idle for our command submission ***/
464 for (counter = 2000; counter > 0; counter--) {
465 /* FIXME: auwtsh, busy waiting.
466 * Hmm, yeah, but this function is probably supposed to be
467 * finished ASAP, so it's probably not such a terribly good
468 * idea to schedule away instead of busy wait.
469 * Maybe let's just keep it as is. */
470 get_cmd_state(hw);
471 /* Test for IDLE state */
472 if (!hw->cmd_status)
473 break;
476 /*** The card doesn't get IDLE, we're in trouble ***/
477 if (counter == 0) {
478 /* uh oh, cmd status still set, now we're in trouble */
479 acxlog((L_BINDEBUG | L_CTL),
480 "Trying to issue a command to the ACX100 but the Command Register is not IDLE\n");
481 goto done;
484 /*** now write the parameters of the command if needed ***/
485 if (pcmdparam != NULL && paramlen != 0) {
486 if (cmd == ACX100_CMD_INTERROGATE) {
487 /* it's an INTERROGATE command, so just pass the length
488 * of parameters to read, as data */
489 write_cmd_Parameters(hw, pcmdparam, 0x4);
490 } else {
491 write_cmd_Parameters(hw, pcmdparam, paramlen);
495 /*** now write the actual command type ***/
496 hw->cmd_type = cmd;
497 write_cmd_type(hw, cmd);
499 /*** is this "execute command" operation? ***/
500 hwWriteRegister16(hw, ACX100_REG_7C,
501 hwReadRegister16(hw, ACX100_REG_7C) | 0x01);
503 /*** wait for IRQ to occur, then ACK it? ***/
504 if (timeout > 120000) {
505 timeout = 120000;
507 timeout *= 20;
508 if (timeout) {
509 for (counter = timeout; counter > 0; counter--) {
510 /* it's a busy wait loop, but we're supposed to be
511 * fast here, so better don't schedule away here? */
512 if ((irqtype =
513 hwReadRegister16(hw, ACX100_STATUS)) & 0x200) {
514 hwWriteRegister16(hw, ACX100_IRQ_ACK, 0x200);
515 break;
520 /*** Save state for debugging ***/
521 get_cmd_state(hw);
522 cmd_status = hw->cmd_status;
524 /*** Put the card in IDLE state ***/
525 hw->cmd_status = 0;
526 write_cmd_status(hw, 0);
528 if ((irqtype | 0xfdff) == 0xfdff) {
529 acxlog(L_CTL,
530 "Polling for an IRQ failed with %X, cmd_status %d. Bailing.\n",
531 irqtype, cmd_status);
532 goto done;
535 if (cmd_status != 1) {
536 switch (cmd_status) {
537 case 0x0:
538 acxlog((L_BINDEBUG | L_CTL),
539 "ctlIssueCommand failed: Idle[TIMEOUT] [%ld uSec]\n",
540 (timeout - counter) * 50);
541 break;
543 case 0x2:
544 acxlog((L_BINDEBUG | L_CTL),
545 "ctlIssueCommand failed: Unknown Command [%ld uSec]\n",
546 (timeout - counter) * 50);
547 break;
549 case 0x3:
550 acxlog((L_BINDEBUG | L_CTL),
551 "ctlIssueCommand failed: INvalid InfoEle [%ld uSec]\n",
552 (timeout - counter) * 50);
553 break;
555 default:
556 acxlog((L_BINDEBUG | L_CTL),
557 "ctlIssueCommand failed: Unknown(0x%x) [%ld uSec]\n",
558 cmd_status, (timeout - counter) * 50);
559 /* cmd_status 0xe might be "value out of range": happens if you
560 * write a value < 1 or > 2 at ctlDot11CurrentTxPowerLevelWrite */
561 break;
563 } else {
564 /*** read in result parameters if needed ***/
565 if (pcmdparam != NULL && paramlen != 0) {
566 if (cmd == ACX100_CMD_INTERROGATE) {
567 read_cmd_Parameters(hw, pcmdparam,
568 paramlen);
571 result = 1;
574 done:
575 FN_EXIT(1, result);
576 return result;
580 /*****************************************************************************
582 * The Upper Layer
584 ****************************************************************************/
586 static short CtlLength[0x14] = {
588 ACX100_RID_ACX_TIMER_LEN,
589 ACX100_RID_POWER_MGMT_LEN,
590 ACX100_RID_QUEUE_CONFIG_LEN,
591 ACX100_RID_BLOCK_SIZE_LEN,
592 ACX100_RID_MEMORY_CONFIG_OPTIONS_LEN,
593 ACX100_RID_RATE_LEN,
594 ACX100_RID_WEP_OPTIONS_LEN,
595 ACX100_RID_MEMORY_MAP_LEN, // ACX100_RID_SSID_LEN,
597 ACX100_RID_ASSOC_ID_LEN,
600 ACX100_RID_FWREV_LEN,
601 ACX100_RID_FCS_ERROR_COUNT_LEN,
602 ACX100_RID_MEDIUM_USAGE_LEN,
603 ACX100_RID_RXCONFIG_LEN,
606 ACX100_RID_FIRMWARE_STATISTICS_LEN
609 static short CtlLengthDot11[0x14] = {
611 ACX100_RID_DOT11_STATION_ID_LEN,
613 ACX100_RID_DOT11_BEACON_PERIOD_LEN,
614 ACX100_RID_DOT11_DTIM_PERIOD_LEN,
615 ACX100_RID_DOT11_SHORT_RETRY_LIMIT_LEN,
616 ACX100_RID_DOT11_LONG_RETRY_LIMIT_LEN,
617 ACX100_RID_DOT11_WEP_DEFAULT_KEY_LEN,
618 ACX100_RID_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN,
620 ACX100_RID_DOT11_CURRENT_REG_DOMAIN_LEN,
621 ACX100_RID_DOT11_CURRENT_ANTENNA_LEN,
623 ACX100_RID_DOT11_TX_POWER_LEVEL_LEN,
624 ACX100_RID_DOT11_CURRENT_CCA_MODE_LEN,
625 ACX100_RID_DOT11_ED_THRESHOLD_LEN,
626 ACX100_RID_DOT11_WEP_DEFAULT_KEY_SET_LEN,
632 /*----------------------------------------------------------------
633 * ctlConfigure
634 * FIXME: acx100_configure
636 * Arguments:
638 * Returns:
640 * Side effects:
642 * Call context:
644 * STATUS:
646 * Comment:
648 *----------------------------------------------------------------*/
650 /* ctlConfigure()
651 * STATUS: should be ok. FINISHED.
653 int ctlConfigure(wlandevice_t * hw, void * pdr, short type)
655 ((memmap_t *)pdr)->type = type;
656 if (type < 0x1000) {
657 ((memmap_t *)pdr)->length = CtlLength[type];
658 return ctlIssueCommand(hw, ACX100_CMD_CONFIGURE, pdr,
659 CtlLength[type] + 4, 5000);
660 } else {
661 ((memmap_t *)pdr)->length = CtlLengthDot11[type-0x1000];
662 return ctlIssueCommand(hw, ACX100_CMD_CONFIGURE, pdr,
663 CtlLengthDot11[type-0x1000] + 4, 5000);
667 /*----------------------------------------------------------------
668 * ctlConfigureLength
669 * FIXME: rename to acx100_configure_length
671 * Arguments:
673 * Returns:
675 * Side effects:
677 * Call context:
679 * STATUS:
681 * Comment:
683 *----------------------------------------------------------------*/
685 /* ctlConfigureLength()
687 int ctlConfigureLength(wlandevice_t * hw, void * pdr, short type, short length)
689 ((memmap_t *)pdr)->type = type;
690 ((memmap_t *)pdr)->length = length;
691 return ctlIssueCommand(hw, ACX100_CMD_CONFIGURE, pdr,
692 length + 4, 5000);
695 /*----------------------------------------------------------------
696 * ctlInterrogate
697 * FIXME: rename to acx100_interrogate
699 * Arguments:
701 * Returns:
703 * Side effects:
705 * Call context:
707 * STATUS:
709 * Comment:
711 *----------------------------------------------------------------*/
713 /* ctlInterrogate()
714 * STATUS: should be ok. FINISHED.
716 int ctlInterrogate(wlandevice_t * hw, void * pdr, short type)
718 ((memmap_t *)pdr)->type = type;
719 if (type < 0x1000) {
720 ((memmap_t *)pdr)->length = CtlLength[type];
721 return ctlIssueCommand(hw, ACX100_CMD_INTERROGATE, pdr,
722 CtlLength[type] + 4, 5000);
723 } else {
724 ((memmap_t *)pdr)->length = CtlLengthDot11[type-0x1000];
725 return ctlIssueCommand(hw, ACX100_CMD_INTERROGATE, pdr,
726 CtlLengthDot11[type-0x1000] + 4, 5000);
731 /*****************************************************************************
733 * MAC Address Stuff
735 ****************************************************************************/
737 /*----------------------------------------------------------------
738 * IsMacAddressZero
739 * FIXME: rename to acx100_is_mac_address_zero
741 * Arguments:
743 * Returns:
745 * Side effects:
747 * Call context:
749 * STATUS:
751 * Comment:
753 *----------------------------------------------------------------*/
755 /* IsMacAddressZero()
756 * STATUS: should be ok. FINISHED.
758 int IsMacAddressZero(mac_t * mac)
760 if ((mac->vala == 0) && (mac->valb == 0)) {
761 return 1;
763 return 0;
765 /*----------------------------------------------------------------
766 * ClearMacAddress
767 * FIXME: rename to acx100_clear_mac_address
769 * Arguments:
771 * Returns:
773 * Side effects:
775 * Call context:
777 * STATUS:
779 * Comment:
781 *----------------------------------------------------------------*/
783 /* ClearMacAddress()
784 * STATUS: should be ok. FINISHED.
786 void ClearMacAddress(mac_t * m)
788 m->vala = 0;
789 m->valb = 0;
791 /*----------------------------------------------------------------
792 * IsMacAddressEqual
793 * FIXME: rename to acx100_is_mac_address_equal
795 * Arguments:
797 * Returns:
799 * Side effects:
801 * Call context:
803 * STATUS:
805 * Comment:
807 *----------------------------------------------------------------*/
809 /* IsMacAddressEqual()
810 * STATUS: should be ok. FINISHED.
812 int IsMacAddressEqual(UINT8 * one, UINT8 * two)
814 if (memcmp(one, two, WLAN_ADDR_LEN))
815 return 0; /* no match */
816 else
817 return 1; /* matched */
820 /*----------------------------------------------------------------
821 * CopyMacAddress
822 * FIXME: rename to acx100_copy_mac_address
824 * Arguments:
826 * Returns:
828 * Side effects:
830 * Call context:
832 * STATUS:
834 * Comment:
836 *----------------------------------------------------------------*/
838 /* CopyMacAddress()
839 * STATUS: should be ok. FINISHED.
841 void CopyMacAddress(UINT8 * to, UINT8 * from)
843 memcpy(to, from, WLAN_ADDR_LEN);
846 /*----------------------------------------------------------------
847 * IsMacAddressGroup
848 * FIXME: rename to acx100_is_mac_address_group
850 * Arguments:
852 * Returns:
854 * Side effects:
856 * Call context:
858 * STATUS:
860 * Comment:
862 *----------------------------------------------------------------*/
864 /* IsMacAddressGroup()
865 * STATUS: should be ok. FINISHED.
867 UINT8 IsMacAddressGroup(mac_t * mac)
869 return mac->vala & 1;
871 /*----------------------------------------------------------------
872 * IsMacAddressDirected
873 * FIXME: rename to acx100_is_mac_address_directed
875 * Arguments:
877 * Returns:
879 * Side effects:
881 * Call context:
883 * STATUS:
885 * Comment:
887 *----------------------------------------------------------------*/
889 /* IsMacAddressDirected()
890 * STATUS: should be ok. FINISHED.
892 UINT8 IsMacAddressDirected(mac_t * mac)
894 if (mac->vala & 1) {
895 return 0;
897 return 1;
900 /*----------------------------------------------------------------
901 * SetMacAddressBroadcast
902 * FIXME: rename to acx100_set_mac_address_broadcast
904 * Arguments:
906 * Returns:
908 * Side effects:
910 * Call context:
912 * STATUS:
914 * Comment:
916 *----------------------------------------------------------------*/
918 /* SetMacAddressBroadcast()
919 * STATUS: should be ok. FINISHED.
921 void SetMacAddressBroadcast(char *mac)
923 memset(mac, 0xff, WLAN_ADDR_LEN);
926 /*----------------------------------------------------------------
927 * IsMacAddressBroadcast
928 * FIXME: rename to acx100_is_mac_address_broadcast
930 * Arguments:
932 * Returns:
934 * Side effects:
936 * Call context:
938 * STATUS:
940 * Comment:
942 *----------------------------------------------------------------*/
944 /* IsMacAddressBroadcast()
945 * STATUS: should be ok. FINISHED.
947 int IsMacAddressBroadcast(mac_t * mac)
949 if ((mac->vala == 0xffffffff) && (mac->valb == 0xffff)) {
950 return 1;
952 return 0;
955 /*----------------------------------------------------------------
956 * IsMacAddressMulticast
957 * FIXME: rename to acx100_is_mac_address_multicast
959 * Arguments:
961 * Returns:
963 * Side effects:
965 * Call context:
967 * STATUS:
969 * Comment:
971 *----------------------------------------------------------------*/
973 /* IsMacAddressMulticast()
974 * STATUS: should be ok. FINISHED.
976 int IsMacAddressMulticast(mac_t * mac)
978 if (mac->vala & 1) {
979 if ((mac->vala == 0xffffffff) && (mac->valb == 0xffff))
980 return 0;
981 else
982 return 1;
984 return 0;
987 /*----------------------------------------------------------------
988 * LogMacAddress
989 * FIXME: rename to acx100_log_mac_address
991 * Arguments:
993 * Returns:
995 * Side effects:
997 * Call context:
999 * STATUS:
1001 * Comment:
1003 *----------------------------------------------------------------*/
1005 /* LogMacAddress()
1006 * STATUS: NEW
1008 void LogMacAddress(int level, UINT8 * mac)
1010 acxlog(level, "%02X.%02X.%02X.%02X.%02X.%02X",
1011 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
1014 /*----------------------------------------------------------------
1015 * acx100_power_led
1018 * Arguments:
1020 * Returns:
1022 * Side effects:
1024 * Call context:
1026 * STATUS:
1028 * Comment:
1030 *----------------------------------------------------------------*/
1032 void acx100_power_led(wlandevice_t *wlandev, int enable)
1034 if (enable)
1035 hwWriteRegister16(wlandev, 0x290, hwReadRegister16(wlandev, 0x290) & ~0x0800);
1036 else
1037 hwWriteRegister16(wlandev, 0x290, hwReadRegister16(wlandev, 0x290) | 0x0800);