^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * IPWireless 3G PCMCIA Network Driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Original code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * by Stephen Blackheath <stephen@blacksapphire.com>,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Ben Martel <benm@symmetric.co.nz>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyrighted as follows:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Copyright (C) 2004 by Symmetric Systems Ltd (NZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Various driver changes and rewrites, port to new kernels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Copyright (C) 2006-2007 Jiri Kosina
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Misc code cleanups and updates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * Copyright (C) 2007 David Sterba
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include "hardware.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include "setup_protocol.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include "network.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include "main.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) static void ipw_send_setup_packet(struct ipw_hardware *hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static void handle_received_SETUP_packet(struct ipw_hardware *ipw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) unsigned int address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) const unsigned char *data, int len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) int is_last);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static void ipwireless_setup_timer(struct timer_list *t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static void handle_received_CTRL_packet(struct ipw_hardware *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) unsigned int channel_idx, const unsigned char *data, int len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) /*#define TIMING_DIAGNOSTICS*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #ifdef TIMING_DIAGNOSTICS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static struct timing_stats {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) unsigned long last_report_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) unsigned long read_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) unsigned long write_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) unsigned long read_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) unsigned long write_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) unsigned long start_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) static void start_timing(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) timing_stats.start_time = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static void end_read_timing(unsigned length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) timing_stats.read_time += (jiffies - start_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) timing_stats.read_bytes += length + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) report_timing();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static void end_write_timing(unsigned length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) timing_stats.write_time += (jiffies - start_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) timing_stats.write_bytes += length + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) report_timing();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static void report_timing(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) unsigned long since = jiffies - timing_stats.last_report_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) /* If it's been more than one second... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) if (since >= HZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) int first = (timing_stats.last_report_time == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) timing_stats.last_report_time = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) if (!first)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) printk(KERN_INFO IPWIRELESS_PCCARD_NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) ": %u us elapsed - read %lu bytes in %u us, wrote %lu bytes in %u us\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) jiffies_to_usecs(since),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) timing_stats.read_bytes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) jiffies_to_usecs(timing_stats.read_time),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) timing_stats.write_bytes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) jiffies_to_usecs(timing_stats.write_time));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) timing_stats.read_time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) timing_stats.write_time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) timing_stats.read_bytes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) timing_stats.write_bytes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) static void start_timing(void) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) static void end_read_timing(unsigned length) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) static void end_write_timing(unsigned length) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /* Imported IPW definitions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define LL_MTU_V1 318
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define LL_MTU_V2 250
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define LL_MTU_MAX (LL_MTU_V1 > LL_MTU_V2 ? LL_MTU_V1 : LL_MTU_V2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define PRIO_DATA 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define PRIO_CTRL 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define PRIO_SETUP 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /* Addresses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #define ADDR_SETUP_PROT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) /* Protocol ids */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) /* Identifier for the Com Data protocol */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) TL_PROTOCOLID_COM_DATA = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /* Identifier for the Com Control protocol */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) TL_PROTOCOLID_COM_CTRL = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /* Identifier for the Setup protocol */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) TL_PROTOCOLID_SETUP = 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /* Number of bytes in NL packet header (cannot do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * sizeof(nl_packet_header) since it's a bitfield) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define NL_FIRST_PACKET_HEADER_SIZE 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) /* Number of bytes in NL packet header (cannot do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * sizeof(nl_packet_header) since it's a bitfield) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #define NL_FOLLOWING_PACKET_HEADER_SIZE 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) struct nl_first_packet_header {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) unsigned char protocol:3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) unsigned char address:3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) unsigned char packet_rank:2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) unsigned char length_lsb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) unsigned char length_msb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) struct nl_packet_header {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) unsigned char protocol:3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) unsigned char address:3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) unsigned char packet_rank:2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /* Value of 'packet_rank' above */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #define NL_INTERMEDIATE_PACKET 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #define NL_LAST_PACKET 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) #define NL_FIRST_PACKET 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) union nl_packet {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /* Network packet header of the first packet (a special case) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) struct nl_first_packet_header hdr_first;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) /* Network packet header of the following packets (if any) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct nl_packet_header hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /* Complete network packet (header + data) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) unsigned char rawpkt[LL_MTU_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) } __attribute__ ((__packed__));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #define HW_VERSION_UNKNOWN -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) #define HW_VERSION_1 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #define HW_VERSION_2 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) /* IPW I/O ports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) #define IOIER 0x00 /* Interrupt Enable Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) #define IOIR 0x02 /* Interrupt Source/ACK register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) #define IODCR 0x04 /* Data Control Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) #define IODRR 0x06 /* Data Read Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) #define IODWR 0x08 /* Data Write Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) #define IOESR 0x0A /* Embedded Driver Status Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) #define IORXR 0x0C /* Rx Fifo Register (Host to Embedded) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) #define IOTXR 0x0E /* Tx Fifo Register (Embedded to Host) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) /* I/O ports and bit definitions for version 1 of the hardware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) /* IER bits*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) #define IER_RXENABLED 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #define IER_TXENABLED 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /* ISR bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) #define IR_RXINTR 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) #define IR_TXINTR 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) /* DCR bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) #define DCR_RXDONE 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) #define DCR_TXDONE 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) #define DCR_RXRESET 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) #define DCR_TXRESET 0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) /* I/O ports and bit definitions for version 2 of the hardware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) struct MEMCCR {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) unsigned short reg_config_option; /* PCCOR: Configuration Option Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) unsigned short reg_config_and_status; /* PCCSR: Configuration and Status Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) unsigned short reg_pin_replacement; /* PCPRR: Pin Replacemant Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) unsigned short reg_socket_and_copy; /* PCSCR: Socket and Copy Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) unsigned short reg_ext_status; /* PCESR: Extendend Status Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) unsigned short reg_io_base; /* PCIOB: I/O Base Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct MEMINFREG {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) unsigned short memreg_tx_old; /* TX Register (R/W) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) unsigned short pad1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) unsigned short memreg_rx_done; /* RXDone Register (R/W) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) unsigned short pad2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) unsigned short memreg_rx; /* RX Register (R/W) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) unsigned short pad3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) unsigned short memreg_pc_interrupt_ack; /* PC intr Ack Register (W) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) unsigned short pad4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) unsigned long memreg_card_present;/* Mask for Host to check (R) for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) * CARD_PRESENT_VALUE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) unsigned short memreg_tx_new; /* TX2 (new) Register (R/W) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) #define CARD_PRESENT_VALUE (0xBEEFCAFEUL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) #define MEMTX_TX 0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) #define MEMRX_RX 0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) #define MEMRX_RX_DONE 0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) #define MEMRX_PCINTACKK 0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) #define NL_NUM_OF_PRIORITIES 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) #define NL_NUM_OF_PROTOCOLS 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) #define NL_NUM_OF_ADDRESSES NO_OF_IPW_CHANNELS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) struct ipw_hardware {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) unsigned int base_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) short hw_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) unsigned short ll_mtu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) int initializing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) int init_loops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) struct timer_list setup_timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) /* Flag if hw is ready to send next packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) int tx_ready;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) /* Count of pending packets to be sent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) int tx_queued;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) struct list_head tx_queue[NL_NUM_OF_PRIORITIES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) int rx_bytes_queued;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) struct list_head rx_queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) /* Pool of rx_packet structures that are not currently used. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) struct list_head rx_pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) int rx_pool_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /* True if reception of data is blocked while userspace processes it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) int blocking_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) /* True if there is RX data ready on the hardware. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) int rx_ready;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) unsigned short last_memtx_serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * Newer versions of the V2 card firmware send serial numbers in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * MemTX register. 'serial_number_detected' is set true when we detect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * a non-zero serial number (indicating the new firmware). Thereafter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * the driver can safely ignore the Timer Recovery re-sends to avoid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * out-of-sync problems.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) int serial_number_detected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) struct work_struct work_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) /* True if we are to send the set-up data to the hardware. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) int to_setup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) /* Card has been removed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) int removed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) /* Saved irq value when we disable the interrupt. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) /* True if this driver is shutting down. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) int shutting_down;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) /* Modem control lines */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) unsigned int control_lines[NL_NUM_OF_ADDRESSES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) struct ipw_rx_packet *packet_assembler[NL_NUM_OF_ADDRESSES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) struct tasklet_struct tasklet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) /* The handle for the network layer, for the sending of events to it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct ipw_network *network;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) struct MEMINFREG __iomem *memory_info_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) struct MEMCCR __iomem *memregs_CCR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) void (*reboot_callback) (void *data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) void *reboot_callback_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) unsigned short __iomem *memreg_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) * Packet info structure for tx packets.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) * Note: not all the fields defined here are required for all protocols
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) struct ipw_tx_packet {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) struct list_head queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) /* channel idx + 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) unsigned char dest_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) /* SETUP, CTRL or DATA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) unsigned char protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) /* Length of data block, which starts at the end of this structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) unsigned short length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) /* Sending state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) /* Offset of where we've sent up to so far */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) unsigned long offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) /* Count of packet fragments, starting at 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) int fragment_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) /* Called after packet is sent and before is freed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) void (*packet_callback) (void *cb_data, unsigned int packet_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) void *callback_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) /* Signals from DTE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) #define COMCTRL_RTS 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) #define COMCTRL_DTR 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) /* Signals from DCE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) #define COMCTRL_CTS 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) #define COMCTRL_DCD 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) #define COMCTRL_DSR 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) #define COMCTRL_RI 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) struct ipw_control_packet_body {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) /* DTE signal or DCE signal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) unsigned char sig_no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) /* 0: set signal, 1: clear signal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) unsigned char value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) } __attribute__ ((__packed__));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) struct ipw_control_packet {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) struct ipw_tx_packet header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) struct ipw_control_packet_body body;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) struct ipw_rx_packet {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) struct list_head queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) unsigned int capacity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) unsigned int length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) unsigned int protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) unsigned int channel_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) static char *data_type(const unsigned char *buf, unsigned length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) struct nl_packet_header *hdr = (struct nl_packet_header *) buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (length == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) return " ";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) if (hdr->packet_rank & NL_FIRST_PACKET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) switch (hdr->protocol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) case TL_PROTOCOLID_COM_DATA: return "DATA ";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) case TL_PROTOCOLID_COM_CTRL: return "CTRL ";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) case TL_PROTOCOLID_SETUP: return "SETUP";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) default: return "???? ";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) return " ";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) #define DUMP_MAX_BYTES 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) static void dump_data_bytes(const char *type, const unsigned char *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) unsigned length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) char prefix[56];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) sprintf(prefix, IPWIRELESS_PCCARD_NAME ": %s %s ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) type, data_type(data, length));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) print_hex_dump_bytes(prefix, 0, (void *)data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) length < DUMP_MAX_BYTES ? length : DUMP_MAX_BYTES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) static void swap_packet_bitfield_to_le(unsigned char *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) #ifdef __BIG_ENDIAN_BITFIELD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) unsigned char tmp = *data, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) * transform bits from aa.bbb.ccc to ccc.bbb.aa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) ret |= (tmp & 0xc0) >> 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) ret |= (tmp & 0x38) >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) ret |= (tmp & 0x07) << 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) *data = ret & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) static void swap_packet_bitfield_from_le(unsigned char *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) #ifdef __BIG_ENDIAN_BITFIELD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) unsigned char tmp = *data, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) * transform bits from ccc.bbb.aa to aa.bbb.ccc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) ret |= (tmp & 0xe0) >> 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) ret |= (tmp & 0x1c) << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) ret |= (tmp & 0x03) << 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) *data = ret & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) static void do_send_fragment(struct ipw_hardware *hw, unsigned char *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) unsigned length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) unsigned i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) start_timing();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) BUG_ON(length > hw->ll_mtu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (ipwireless_debug)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) dump_data_bytes("send", data, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) spin_lock_irqsave(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) hw->tx_ready = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) swap_packet_bitfield_to_le(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) if (hw->hw_version == HW_VERSION_1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) outw((unsigned short) length, hw->base_port + IODWR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) for (i = 0; i < length; i += 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) unsigned short d = data[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) __le16 raw_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (i + 1 < length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) d |= data[i + 1] << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) raw_data = cpu_to_le16(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) outw(raw_data, hw->base_port + IODWR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) outw(DCR_TXDONE, hw->base_port + IODCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) } else if (hw->hw_version == HW_VERSION_2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) outw((unsigned short) length, hw->base_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) for (i = 0; i < length; i += 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) unsigned short d = data[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) __le16 raw_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) if (i + 1 < length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) d |= data[i + 1] << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) raw_data = cpu_to_le16(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) outw(raw_data, hw->base_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) while ((i & 3) != 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) outw((unsigned short) 0xDEAD, hw->base_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) i += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) writew(MEMRX_RX, &hw->memory_info_regs->memreg_rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) spin_unlock_irqrestore(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) end_write_timing(length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) static void do_send_packet(struct ipw_hardware *hw, struct ipw_tx_packet *packet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) unsigned short fragment_data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) unsigned short data_left = packet->length - packet->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) unsigned short header_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) union nl_packet pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) header_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) (packet->fragment_count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) ? NL_FIRST_PACKET_HEADER_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) : NL_FOLLOWING_PACKET_HEADER_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) fragment_data_len = hw->ll_mtu - header_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) if (data_left < fragment_data_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) fragment_data_len = data_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) * hdr_first is now in machine bitfield order, which will be swapped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) * to le just before it goes to hw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) pkt.hdr_first.protocol = packet->protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) pkt.hdr_first.address = packet->dest_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) pkt.hdr_first.packet_rank = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) /* First packet? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) if (packet->fragment_count == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) pkt.hdr_first.packet_rank |= NL_FIRST_PACKET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) pkt.hdr_first.length_lsb = (unsigned char) packet->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) pkt.hdr_first.length_msb =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) (unsigned char) (packet->length >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) memcpy(pkt.rawpkt + header_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) ((unsigned char *) packet) + sizeof(struct ipw_tx_packet) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) packet->offset, fragment_data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) packet->offset += fragment_data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) packet->fragment_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) /* Last packet? (May also be first packet.) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (packet->offset == packet->length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) pkt.hdr_first.packet_rank |= NL_LAST_PACKET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) do_send_fragment(hw, pkt.rawpkt, header_size + fragment_data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) /* If this packet has unsent data, then re-queue it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (packet->offset < packet->length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) * Re-queue it at the head of the highest priority queue so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) * it goes before all other packets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) spin_lock_irqsave(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) list_add(&packet->queue, &hw->tx_queue[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) hw->tx_queued++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) spin_unlock_irqrestore(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) if (packet->packet_callback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) packet->packet_callback(packet->callback_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) packet->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) kfree(packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) static void ipw_setup_hardware(struct ipw_hardware *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) spin_lock_irqsave(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) if (hw->hw_version == HW_VERSION_1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) /* Reset RX FIFO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) outw(DCR_RXRESET, hw->base_port + IODCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) /* SB: Reset TX FIFO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) outw(DCR_TXRESET, hw->base_port + IODCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) /* Enable TX and RX interrupts. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) outw(IER_TXENABLED | IER_RXENABLED, hw->base_port + IOIER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) * Set INTRACK bit (bit 0), which means we must explicitly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) * acknowledge interrupts by clearing bit 2 of reg_config_and_status.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) unsigned short csr = readw(&hw->memregs_CCR->reg_config_and_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) csr |= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) writew(csr, &hw->memregs_CCR->reg_config_and_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) spin_unlock_irqrestore(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) * If 'packet' is NULL, then this function allocates a new packet, setting its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) * length to 0 and ensuring it has the specified minimum amount of free space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) * If 'packet' is not NULL, then this function enlarges it if it doesn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) * have the specified minimum amount of free space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) static struct ipw_rx_packet *pool_allocate(struct ipw_hardware *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) struct ipw_rx_packet *packet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) int minimum_free_space)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) if (!packet) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) spin_lock_irqsave(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) if (!list_empty(&hw->rx_pool)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) packet = list_first_entry(&hw->rx_pool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) struct ipw_rx_packet, queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) hw->rx_pool_size--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) spin_unlock_irqrestore(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) list_del(&packet->queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) const int min_capacity =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) ipwireless_ppp_mru(hw->network) + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) int new_capacity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) spin_unlock_irqrestore(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) new_capacity =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) (minimum_free_space > min_capacity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) ? minimum_free_space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) : min_capacity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) packet = kmalloc(sizeof(struct ipw_rx_packet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) + new_capacity, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) if (!packet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) packet->capacity = new_capacity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) packet->length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) if (packet->length + minimum_free_space > packet->capacity) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) struct ipw_rx_packet *old_packet = packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) packet = kmalloc(sizeof(struct ipw_rx_packet) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) old_packet->length + minimum_free_space,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) if (!packet) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) kfree(old_packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) memcpy(packet, old_packet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) sizeof(struct ipw_rx_packet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) + old_packet->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) packet->capacity = old_packet->length + minimum_free_space;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) kfree(old_packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) return packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) static void pool_free(struct ipw_hardware *hw, struct ipw_rx_packet *packet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) if (hw->rx_pool_size > 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) kfree(packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) hw->rx_pool_size++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) list_add(&packet->queue, &hw->rx_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) static void queue_received_packet(struct ipw_hardware *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) unsigned int protocol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) unsigned int address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) const unsigned char *data, int length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) int is_last)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) unsigned int channel_idx = address - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) struct ipw_rx_packet *packet = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) /* Discard packet if channel index is out of range. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) if (channel_idx >= NL_NUM_OF_ADDRESSES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) printk(KERN_INFO IPWIRELESS_PCCARD_NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) ": data packet has bad address %u\n", address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) * ->packet_assembler is safe to touch unlocked, this is the only place
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) if (protocol == TL_PROTOCOLID_COM_DATA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) struct ipw_rx_packet **assem =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) &hw->packet_assembler[channel_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) * Create a new packet, or assembler already contains one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) * enlarge it by 'length' bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) (*assem) = pool_allocate(hw, *assem, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) if (!(*assem)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) printk(KERN_ERR IPWIRELESS_PCCARD_NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) ": no memory for incoming data packet, dropped!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) (*assem)->protocol = protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) (*assem)->channel_idx = channel_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) /* Append this packet data onto existing data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) memcpy((unsigned char *)(*assem) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) sizeof(struct ipw_rx_packet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) + (*assem)->length, data, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) (*assem)->length += length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) if (is_last) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) packet = *assem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) *assem = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) /* Count queued DATA bytes only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) spin_lock_irqsave(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) hw->rx_bytes_queued += packet->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) spin_unlock_irqrestore(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) /* If it's a CTRL packet, don't assemble, just queue it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) packet = pool_allocate(hw, NULL, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) if (!packet) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) printk(KERN_ERR IPWIRELESS_PCCARD_NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) ": no memory for incoming ctrl packet, dropped!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) packet->protocol = protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) packet->channel_idx = channel_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) memcpy((unsigned char *)packet + sizeof(struct ipw_rx_packet),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) data, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) packet->length = length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) * If this is the last packet, then send the assembled packet on to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) * network layer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) if (packet) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) spin_lock_irqsave(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) list_add_tail(&packet->queue, &hw->rx_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) /* Block reception of incoming packets if queue is full. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) hw->blocking_rx =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) (hw->rx_bytes_queued >= IPWIRELESS_RX_QUEUE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) spin_unlock_irqrestore(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) schedule_work(&hw->work_rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) * Workqueue callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) static void ipw_receive_data_work(struct work_struct *work_rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) struct ipw_hardware *hw =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) container_of(work_rx, struct ipw_hardware, work_rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) spin_lock_irqsave(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) while (!list_empty(&hw->rx_queue)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) struct ipw_rx_packet *packet =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) list_first_entry(&hw->rx_queue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) struct ipw_rx_packet, queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) if (hw->shutting_down)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) list_del(&packet->queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) * Note: ipwireless_network_packet_received must be called in a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) * process context (i.e. via schedule_work) because the tty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) * output code can sleep in the tty_flip_buffer_push call.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) if (packet->protocol == TL_PROTOCOLID_COM_DATA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) if (hw->network != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) /* If the network hasn't been disconnected. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) spin_unlock_irqrestore(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) * This must run unlocked due to tty processing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) * and mutex locking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) ipwireless_network_packet_received(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) hw->network,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) packet->channel_idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) (unsigned char *)packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) + sizeof(struct ipw_rx_packet),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) packet->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) spin_lock_irqsave(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) /* Count queued DATA bytes only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) hw->rx_bytes_queued -= packet->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) * This is safe to be called locked, callchain does
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) * not block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) handle_received_CTRL_packet(hw, packet->channel_idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) (unsigned char *)packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) + sizeof(struct ipw_rx_packet),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) packet->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) pool_free(hw, packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) * Unblock reception of incoming packets if queue is no longer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) * full.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) hw->blocking_rx =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) hw->rx_bytes_queued >= IPWIRELESS_RX_QUEUE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) if (hw->shutting_down)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) spin_unlock_irqrestore(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) static void handle_received_CTRL_packet(struct ipw_hardware *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) unsigned int channel_idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) const unsigned char *data, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) const struct ipw_control_packet_body *body =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) (const struct ipw_control_packet_body *) data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) unsigned int changed_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) if (len != sizeof(struct ipw_control_packet_body)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) printk(KERN_INFO IPWIRELESS_PCCARD_NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) ": control packet was %d bytes - wrong size!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) switch (body->sig_no) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) case COMCTRL_CTS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) changed_mask = IPW_CONTROL_LINE_CTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) case COMCTRL_DCD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) changed_mask = IPW_CONTROL_LINE_DCD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) case COMCTRL_DSR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) changed_mask = IPW_CONTROL_LINE_DSR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) case COMCTRL_RI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) changed_mask = IPW_CONTROL_LINE_RI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) changed_mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) if (changed_mask != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) if (body->value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) hw->control_lines[channel_idx] |= changed_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) hw->control_lines[channel_idx] &= ~changed_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) if (hw->network)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) ipwireless_network_notify_control_line_change(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) hw->network,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) channel_idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) hw->control_lines[channel_idx],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) changed_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) static void handle_received_packet(struct ipw_hardware *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) const union nl_packet *packet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) unsigned short len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) unsigned int protocol = packet->hdr.protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) unsigned int address = packet->hdr.address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) unsigned int header_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) const unsigned char *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) unsigned int data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) int is_last = packet->hdr.packet_rank & NL_LAST_PACKET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) if (packet->hdr.packet_rank & NL_FIRST_PACKET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) header_length = NL_FIRST_PACKET_HEADER_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) header_length = NL_FOLLOWING_PACKET_HEADER_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) data = packet->rawpkt + header_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) data_len = len - header_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) switch (protocol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) case TL_PROTOCOLID_COM_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) case TL_PROTOCOLID_COM_CTRL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) queue_received_packet(hw, protocol, address, data, data_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) is_last);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) case TL_PROTOCOLID_SETUP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) handle_received_SETUP_packet(hw, address, data, data_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) is_last);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) static void acknowledge_data_read(struct ipw_hardware *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) if (hw->hw_version == HW_VERSION_1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) outw(DCR_RXDONE, hw->base_port + IODCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) writew(MEMRX_PCINTACKK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) &hw->memory_info_regs->memreg_pc_interrupt_ack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) * Retrieve a packet from the IPW hardware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) static void do_receive_packet(struct ipw_hardware *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) unsigned len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) unsigned i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) unsigned char pkt[LL_MTU_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) start_timing();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) if (hw->hw_version == HW_VERSION_1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) len = inw(hw->base_port + IODRR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) if (len > hw->ll_mtu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) printk(KERN_INFO IPWIRELESS_PCCARD_NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) ": received a packet of %u bytes - longer than the MTU!\n", len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) outw(DCR_RXDONE | DCR_RXRESET, hw->base_port + IODCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) for (i = 0; i < len; i += 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) __le16 raw_data = inw(hw->base_port + IODRR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) unsigned short data = le16_to_cpu(raw_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) pkt[i] = (unsigned char) data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) pkt[i + 1] = (unsigned char) (data >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) len = inw(hw->base_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) if (len > hw->ll_mtu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) printk(KERN_INFO IPWIRELESS_PCCARD_NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) ": received a packet of %u bytes - longer than the MTU!\n", len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) writew(MEMRX_PCINTACKK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) &hw->memory_info_regs->memreg_pc_interrupt_ack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) for (i = 0; i < len; i += 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) __le16 raw_data = inw(hw->base_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) unsigned short data = le16_to_cpu(raw_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) pkt[i] = (unsigned char) data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) pkt[i + 1] = (unsigned char) (data >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) while ((i & 3) != 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) inw(hw->base_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) i += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) acknowledge_data_read(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) swap_packet_bitfield_from_le(pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) if (ipwireless_debug)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) dump_data_bytes("recv", pkt, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) handle_received_packet(hw, (union nl_packet *) pkt, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) end_read_timing(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) static int get_current_packet_priority(struct ipw_hardware *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) * If we're initializing, don't send anything of higher priority than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) * PRIO_SETUP. The network layer therefore need not care about
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) * hardware initialization - any of its stuff will simply be queued
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) * until setup is complete.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) return (hw->to_setup || hw->initializing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) ? PRIO_SETUP + 1 : NL_NUM_OF_PRIORITIES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) * return 1 if something has been received from hw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) static int get_packets_from_hw(struct ipw_hardware *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) int received = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) spin_lock_irqsave(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) while (hw->rx_ready && !hw->blocking_rx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) received = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) hw->rx_ready--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) spin_unlock_irqrestore(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) do_receive_packet(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) spin_lock_irqsave(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) spin_unlock_irqrestore(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) return received;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) * Send pending packet up to given priority, prioritize SETUP data until
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) * hardware is fully setup.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) * return 1 if more packets can be sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) static int send_pending_packet(struct ipw_hardware *hw, int priority_limit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) int more_to_send = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) spin_lock_irqsave(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) if (hw->tx_queued && hw->tx_ready) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) int priority;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) struct ipw_tx_packet *packet = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) /* Pick a packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) for (priority = 0; priority < priority_limit; priority++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) if (!list_empty(&hw->tx_queue[priority])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) packet = list_first_entry(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) &hw->tx_queue[priority],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) struct ipw_tx_packet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) hw->tx_queued--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) list_del(&packet->queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) if (!packet) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) hw->tx_queued = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) spin_unlock_irqrestore(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) spin_unlock_irqrestore(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) /* Send */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) do_send_packet(hw, packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) /* Check if more to send */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) spin_lock_irqsave(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) for (priority = 0; priority < priority_limit; priority++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) if (!list_empty(&hw->tx_queue[priority])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) more_to_send = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) if (!more_to_send)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) hw->tx_queued = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) spin_unlock_irqrestore(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) return more_to_send;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) * Send and receive all queued packets.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) static void ipwireless_do_tasklet(struct tasklet_struct *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) struct ipw_hardware *hw = from_tasklet(hw, t, tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) spin_lock_irqsave(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) if (hw->shutting_down) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) spin_unlock_irqrestore(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) if (hw->to_setup == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) * Initial setup data sent to hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) hw->to_setup = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) spin_unlock_irqrestore(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) ipw_setup_hardware(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) ipw_send_setup_packet(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) send_pending_packet(hw, PRIO_SETUP + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) get_packets_from_hw(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) int priority_limit = get_current_packet_priority(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) int again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) spin_unlock_irqrestore(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) again = send_pending_packet(hw, priority_limit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) again |= get_packets_from_hw(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) } while (again);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) * return true if the card is physically present.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) static int is_card_present(struct ipw_hardware *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) if (hw->hw_version == HW_VERSION_1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) return inw(hw->base_port + IOIR) != 0xFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) return readl(&hw->memory_info_regs->memreg_card_present) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) CARD_PRESENT_VALUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) static irqreturn_t ipwireless_handle_v1_interrupt(int irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) struct ipw_hardware *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) unsigned short irqn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) irqn = inw(hw->base_port + IOIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) /* Check if card is present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) if (irqn == 0xFFFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) else if (irqn != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) unsigned short ack = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) /* Transmit complete. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) if (irqn & IR_TXINTR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) ack |= IR_TXINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) spin_lock_irqsave(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) hw->tx_ready = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) spin_unlock_irqrestore(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) /* Received data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) if (irqn & IR_RXINTR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) ack |= IR_RXINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) spin_lock_irqsave(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) hw->rx_ready++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) spin_unlock_irqrestore(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) if (ack != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) outw(ack, hw->base_port + IOIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) tasklet_schedule(&hw->tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) static void acknowledge_pcmcia_interrupt(struct ipw_hardware *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) unsigned short csr = readw(&hw->memregs_CCR->reg_config_and_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) csr &= 0xfffd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) writew(csr, &hw->memregs_CCR->reg_config_and_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) static irqreturn_t ipwireless_handle_v2_v3_interrupt(int irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) struct ipw_hardware *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) int tx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) int rx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) int rx_repeat = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) int try_mem_tx_old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) unsigned short memtx = readw(hw->memreg_tx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) unsigned short memtx_serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) unsigned short memrxdone =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) readw(&hw->memory_info_regs->memreg_rx_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) try_mem_tx_old = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) /* check whether the interrupt was generated by ipwireless card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) if (!(memtx & MEMTX_TX) && !(memrxdone & MEMRX_RX_DONE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) /* check if the card uses memreg_tx_old register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) if (hw->memreg_tx == &hw->memory_info_regs->memreg_tx_new) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) memtx = readw(&hw->memory_info_regs->memreg_tx_old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) if (memtx & MEMTX_TX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) printk(KERN_INFO IPWIRELESS_PCCARD_NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) ": Using memreg_tx_old\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) hw->memreg_tx =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) &hw->memory_info_regs->memreg_tx_old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) * See if the card is physically present. Note that while it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) * powering up, it appears not to be present.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) if (!is_card_present(hw)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) acknowledge_pcmcia_interrupt(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) memtx_serial = memtx & (unsigned short) 0xff00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) if (memtx & MEMTX_TX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) writew(memtx_serial, hw->memreg_tx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) if (hw->serial_number_detected) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) if (memtx_serial != hw->last_memtx_serial) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) hw->last_memtx_serial = memtx_serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) spin_lock_irqsave(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) hw->rx_ready++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) spin_unlock_irqrestore(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) rx = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) /* Ignore 'Timer Recovery' duplicates. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) rx_repeat = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) * If a non-zero serial number is seen, then enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) * serial number checking.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) if (memtx_serial != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) hw->serial_number_detected = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) ": memreg_tx serial num detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) spin_lock_irqsave(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) hw->rx_ready++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) spin_unlock_irqrestore(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) rx = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) if (memrxdone & MEMRX_RX_DONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) writew(0, &hw->memory_info_regs->memreg_rx_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) spin_lock_irqsave(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) hw->tx_ready = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) spin_unlock_irqrestore(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) tx = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) if (tx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) writew(MEMRX_PCINTACKK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) &hw->memory_info_regs->memreg_pc_interrupt_ack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) acknowledge_pcmcia_interrupt(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) if (tx || rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) tasklet_schedule(&hw->tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) else if (!rx_repeat) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) if (hw->memreg_tx == &hw->memory_info_regs->memreg_tx_new) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) if (hw->serial_number_detected)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) printk(KERN_WARNING IPWIRELESS_PCCARD_NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) ": spurious interrupt - new_tx mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) printk(KERN_WARNING IPWIRELESS_PCCARD_NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) ": no valid memreg_tx value - switching to the old memreg_tx\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) hw->memreg_tx =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) &hw->memory_info_regs->memreg_tx_old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) try_mem_tx_old = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) printk(KERN_WARNING IPWIRELESS_PCCARD_NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) ": spurious interrupt - old_tx mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) } while (try_mem_tx_old == 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) irqreturn_t ipwireless_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) struct ipw_dev *ipw = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) if (ipw->hardware->hw_version == HW_VERSION_1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) return ipwireless_handle_v1_interrupt(irq, ipw->hardware);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) return ipwireless_handle_v2_v3_interrupt(irq, ipw->hardware);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) static void flush_packets_to_hw(struct ipw_hardware *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) int priority_limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) spin_lock_irqsave(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) priority_limit = get_current_packet_priority(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) spin_unlock_irqrestore(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) while (send_pending_packet(hw, priority_limit));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) static void send_packet(struct ipw_hardware *hw, int priority,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) struct ipw_tx_packet *packet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) spin_lock_irqsave(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) list_add_tail(&packet->queue, &hw->tx_queue[priority]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) hw->tx_queued++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) spin_unlock_irqrestore(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) flush_packets_to_hw(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) /* Create data packet, non-atomic allocation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) static void *alloc_data_packet(int data_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) unsigned char dest_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) unsigned char protocol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) struct ipw_tx_packet *packet = kzalloc(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) sizeof(struct ipw_tx_packet) + data_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) if (!packet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) INIT_LIST_HEAD(&packet->queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) packet->dest_addr = dest_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) packet->protocol = protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) packet->length = data_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) return packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) static void *alloc_ctrl_packet(int header_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) unsigned char dest_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) unsigned char protocol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) unsigned char sig_no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) * sig_no is located right after ipw_tx_packet struct in every
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) * CTRL or SETUP packets, we can use ipw_control_packet as a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) * common struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) struct ipw_control_packet *packet = kzalloc(header_size, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) if (!packet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) INIT_LIST_HEAD(&packet->header.queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) packet->header.dest_addr = dest_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) packet->header.protocol = protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) packet->header.length = header_size - sizeof(struct ipw_tx_packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) packet->body.sig_no = sig_no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) return packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) int ipwireless_send_packet(struct ipw_hardware *hw, unsigned int channel_idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) const unsigned char *data, unsigned int length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) void (*callback) (void *cb, unsigned int length),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) void *callback_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) struct ipw_tx_packet *packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) packet = alloc_data_packet(length, (channel_idx + 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) TL_PROTOCOLID_COM_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) if (!packet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) packet->packet_callback = callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) packet->callback_data = callback_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) memcpy((unsigned char *) packet + sizeof(struct ipw_tx_packet), data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) send_packet(hw, PRIO_DATA, packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) static int set_control_line(struct ipw_hardware *hw, int prio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) unsigned int channel_idx, int line, int state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) struct ipw_control_packet *packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) int protocolid = TL_PROTOCOLID_COM_CTRL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) if (prio == PRIO_SETUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) protocolid = TL_PROTOCOLID_SETUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) packet = alloc_ctrl_packet(sizeof(struct ipw_control_packet),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) (channel_idx + 1), protocolid, line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) if (!packet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) packet->header.length = sizeof(struct ipw_control_packet_body);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) packet->body.value = (state == 0 ? 0 : 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) send_packet(hw, prio, &packet->header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) static int set_DTR(struct ipw_hardware *hw, int priority,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) unsigned int channel_idx, int state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) if (state != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) hw->control_lines[channel_idx] |= IPW_CONTROL_LINE_DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) hw->control_lines[channel_idx] &= ~IPW_CONTROL_LINE_DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) return set_control_line(hw, priority, channel_idx, COMCTRL_DTR, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) static int set_RTS(struct ipw_hardware *hw, int priority,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) unsigned int channel_idx, int state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) if (state != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) hw->control_lines[channel_idx] |= IPW_CONTROL_LINE_RTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) hw->control_lines[channel_idx] &= ~IPW_CONTROL_LINE_RTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) return set_control_line(hw, priority, channel_idx, COMCTRL_RTS, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) int ipwireless_set_DTR(struct ipw_hardware *hw, unsigned int channel_idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) int state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) return set_DTR(hw, PRIO_CTRL, channel_idx, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) int ipwireless_set_RTS(struct ipw_hardware *hw, unsigned int channel_idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) int state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) return set_RTS(hw, PRIO_CTRL, channel_idx, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) struct ipw_setup_get_version_query_packet {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) struct ipw_tx_packet header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) struct tl_setup_get_version_qry body;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) struct ipw_setup_config_packet {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) struct ipw_tx_packet header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) struct tl_setup_config_msg body;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) struct ipw_setup_config_done_packet {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) struct ipw_tx_packet header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) struct tl_setup_config_done_msg body;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) struct ipw_setup_open_packet {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) struct ipw_tx_packet header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) struct tl_setup_open_msg body;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) struct ipw_setup_info_packet {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) struct ipw_tx_packet header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) struct tl_setup_info_msg body;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) struct ipw_setup_reboot_msg_ack {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) struct ipw_tx_packet header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) struct TlSetupRebootMsgAck body;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) /* This handles the actual initialization of the card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) static void __handle_setup_get_version_rsp(struct ipw_hardware *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) struct ipw_setup_config_packet *config_packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) struct ipw_setup_config_done_packet *config_done_packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) struct ipw_setup_open_packet *open_packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) struct ipw_setup_info_packet *info_packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) int port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) unsigned int channel_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) /* generate config packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) for (port = 1; port <= NL_NUM_OF_ADDRESSES; port++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) config_packet = alloc_ctrl_packet(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) sizeof(struct ipw_setup_config_packet),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) ADDR_SETUP_PROT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) TL_PROTOCOLID_SETUP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) TL_SETUP_SIGNO_CONFIG_MSG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) if (!config_packet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) goto exit_nomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) config_packet->header.length = sizeof(struct tl_setup_config_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) config_packet->body.port_no = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) config_packet->body.prio_data = PRIO_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) config_packet->body.prio_ctrl = PRIO_CTRL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) send_packet(hw, PRIO_SETUP, &config_packet->header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) config_done_packet = alloc_ctrl_packet(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) sizeof(struct ipw_setup_config_done_packet),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) ADDR_SETUP_PROT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) TL_PROTOCOLID_SETUP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) TL_SETUP_SIGNO_CONFIG_DONE_MSG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) if (!config_done_packet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) goto exit_nomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) config_done_packet->header.length = sizeof(struct tl_setup_config_done_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) send_packet(hw, PRIO_SETUP, &config_done_packet->header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) /* generate open packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) for (port = 1; port <= NL_NUM_OF_ADDRESSES; port++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) open_packet = alloc_ctrl_packet(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) sizeof(struct ipw_setup_open_packet),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) ADDR_SETUP_PROT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) TL_PROTOCOLID_SETUP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) TL_SETUP_SIGNO_OPEN_MSG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) if (!open_packet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) goto exit_nomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) open_packet->header.length = sizeof(struct tl_setup_open_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) open_packet->body.port_no = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) send_packet(hw, PRIO_SETUP, &open_packet->header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) for (channel_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) channel_idx < NL_NUM_OF_ADDRESSES; channel_idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) ret = set_DTR(hw, PRIO_SETUP, channel_idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) (hw->control_lines[channel_idx] &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) IPW_CONTROL_LINE_DTR) != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) printk(KERN_ERR IPWIRELESS_PCCARD_NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) ": error setting DTR (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) ret = set_RTS(hw, PRIO_SETUP, channel_idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) (hw->control_lines [channel_idx] &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) IPW_CONTROL_LINE_RTS) != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) printk(KERN_ERR IPWIRELESS_PCCARD_NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) ": error setting RTS (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) * For NDIS we assume that we are using sync PPP frames, for COM async.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) * This driver uses NDIS mode too. We don't bother with translation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) * from async -> sync PPP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) info_packet = alloc_ctrl_packet(sizeof(struct ipw_setup_info_packet),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) ADDR_SETUP_PROT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) TL_PROTOCOLID_SETUP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) TL_SETUP_SIGNO_INFO_MSG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) if (!info_packet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) goto exit_nomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) info_packet->header.length = sizeof(struct tl_setup_info_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) info_packet->body.driver_type = NDISWAN_DRIVER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) info_packet->body.major_version = NDISWAN_DRIVER_MAJOR_VERSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) info_packet->body.minor_version = NDISWAN_DRIVER_MINOR_VERSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) send_packet(hw, PRIO_SETUP, &info_packet->header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) /* Initialization is now complete, so we clear the 'to_setup' flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) hw->to_setup = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) exit_nomem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) printk(KERN_ERR IPWIRELESS_PCCARD_NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) ": not enough memory to alloc control packet\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) hw->to_setup = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) static void handle_setup_get_version_rsp(struct ipw_hardware *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) unsigned char vers_no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) del_timer(&hw->setup_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) hw->initializing = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) printk(KERN_INFO IPWIRELESS_PCCARD_NAME ": card is ready.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) if (vers_no == TL_SETUP_VERSION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) __handle_setup_get_version_rsp(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) printk(KERN_ERR IPWIRELESS_PCCARD_NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) ": invalid hardware version no %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) (unsigned int) vers_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) static void ipw_send_setup_packet(struct ipw_hardware *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) struct ipw_setup_get_version_query_packet *ver_packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) ver_packet = alloc_ctrl_packet(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) sizeof(struct ipw_setup_get_version_query_packet),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) ADDR_SETUP_PROT, TL_PROTOCOLID_SETUP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) TL_SETUP_SIGNO_GET_VERSION_QRY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) if (!ver_packet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) ver_packet->header.length = sizeof(struct tl_setup_get_version_qry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) * Response is handled in handle_received_SETUP_packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) send_packet(hw, PRIO_SETUP, &ver_packet->header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) static void handle_received_SETUP_packet(struct ipw_hardware *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) unsigned int address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) const unsigned char *data, int len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) int is_last)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) const union ipw_setup_rx_msg *rx_msg = (const union ipw_setup_rx_msg *) data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) if (address != ADDR_SETUP_PROT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) printk(KERN_INFO IPWIRELESS_PCCARD_NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) ": setup packet has bad address %d\n", address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) switch (rx_msg->sig_no) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) case TL_SETUP_SIGNO_GET_VERSION_RSP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) if (hw->to_setup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) handle_setup_get_version_rsp(hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) rx_msg->version_rsp_msg.version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) case TL_SETUP_SIGNO_OPEN_MSG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) if (ipwireless_debug) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) unsigned int channel_idx = rx_msg->open_msg.port_no - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) printk(KERN_INFO IPWIRELESS_PCCARD_NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) ": OPEN_MSG [channel %u] reply received\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) channel_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) case TL_SETUP_SIGNO_INFO_MSG_ACK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) if (ipwireless_debug)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) ": card successfully configured as NDISWAN\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) case TL_SETUP_SIGNO_REBOOT_MSG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) if (hw->to_setup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) ": Setup not completed - ignoring reboot msg\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) struct ipw_setup_reboot_msg_ack *packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) ": Acknowledging REBOOT message\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) packet = alloc_ctrl_packet(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) sizeof(struct ipw_setup_reboot_msg_ack),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) ADDR_SETUP_PROT, TL_PROTOCOLID_SETUP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) TL_SETUP_SIGNO_REBOOT_MSG_ACK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) if (!packet) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) pr_err(IPWIRELESS_PCCARD_NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) ": Not enough memory to send reboot packet");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) packet->header.length =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) sizeof(struct TlSetupRebootMsgAck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) send_packet(hw, PRIO_SETUP, &packet->header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) if (hw->reboot_callback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) hw->reboot_callback(hw->reboot_callback_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) printk(KERN_INFO IPWIRELESS_PCCARD_NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) ": unknown setup message %u received\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) (unsigned int) rx_msg->sig_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) static void do_close_hardware(struct ipw_hardware *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) unsigned int irqn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) if (hw->hw_version == HW_VERSION_1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) /* Disable TX and RX interrupts. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) outw(0, hw->base_port + IOIER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) /* Acknowledge any outstanding interrupt requests */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) irqn = inw(hw->base_port + IOIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) if (irqn & IR_TXINTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) outw(IR_TXINTR, hw->base_port + IOIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) if (irqn & IR_RXINTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) outw(IR_RXINTR, hw->base_port + IOIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) synchronize_irq(hw->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) struct ipw_hardware *ipwireless_hardware_create(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) struct ipw_hardware *hw =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) kzalloc(sizeof(struct ipw_hardware), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) if (!hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) hw->irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) hw->initializing = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) hw->tx_ready = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) hw->rx_bytes_queued = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) hw->rx_pool_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) hw->last_memtx_serial = (unsigned short) 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) for (i = 0; i < NL_NUM_OF_PRIORITIES; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) INIT_LIST_HEAD(&hw->tx_queue[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) INIT_LIST_HEAD(&hw->rx_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) INIT_LIST_HEAD(&hw->rx_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) spin_lock_init(&hw->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) tasklet_setup(&hw->tasklet, ipwireless_do_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) INIT_WORK(&hw->work_rx, ipw_receive_data_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) timer_setup(&hw->setup_timer, ipwireless_setup_timer, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) return hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) void ipwireless_init_hardware_v1(struct ipw_hardware *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) unsigned int base_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) void __iomem *attr_memory,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) void __iomem *common_memory,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) int is_v2_card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) void (*reboot_callback) (void *data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) void *reboot_callback_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) if (hw->removed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) hw->removed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) enable_irq(hw->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) hw->base_port = base_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) hw->hw_version = (is_v2_card ? HW_VERSION_2 : HW_VERSION_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) hw->ll_mtu = (hw->hw_version == HW_VERSION_1 ? LL_MTU_V1 : LL_MTU_V2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) hw->memregs_CCR = (struct MEMCCR __iomem *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) ((unsigned short __iomem *) attr_memory + 0x200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) hw->memory_info_regs = (struct MEMINFREG __iomem *) common_memory;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) hw->memreg_tx = &hw->memory_info_regs->memreg_tx_new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) hw->reboot_callback = reboot_callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) hw->reboot_callback_data = reboot_callback_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) void ipwireless_init_hardware_v2_v3(struct ipw_hardware *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) hw->initializing = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) hw->init_loops = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) printk(KERN_INFO IPWIRELESS_PCCARD_NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) ": waiting for card to start up...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) ipwireless_setup_timer(&hw->setup_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) static void ipwireless_setup_timer(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) struct ipw_hardware *hw = from_timer(hw, t, setup_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) hw->init_loops++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) if (hw->init_loops == TL_SETUP_MAX_VERSION_QRY &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) hw->hw_version == HW_VERSION_2 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) hw->memreg_tx == &hw->memory_info_regs->memreg_tx_new) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) printk(KERN_INFO IPWIRELESS_PCCARD_NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) ": failed to startup using TX2, trying TX\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) hw->memreg_tx = &hw->memory_info_regs->memreg_tx_old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) hw->init_loops = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) /* Give up after a certain number of retries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) if (hw->init_loops == TL_SETUP_MAX_VERSION_QRY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) printk(KERN_INFO IPWIRELESS_PCCARD_NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) ": card failed to start up!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) hw->initializing = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) /* Do not attempt to write to the board if it is not present. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) if (is_card_present(hw)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) spin_lock_irqsave(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) hw->to_setup = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) hw->tx_ready = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) spin_unlock_irqrestore(&hw->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) tasklet_schedule(&hw->tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) mod_timer(&hw->setup_timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) jiffies + msecs_to_jiffies(TL_SETUP_VERSION_QRY_TMO));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) * Stop any interrupts from executing so that, once this function returns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) * other layers of the driver can be sure they won't get any more callbacks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) * Thus must be called on a proper process context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) void ipwireless_stop_interrupts(struct ipw_hardware *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) if (!hw->shutting_down) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) /* Tell everyone we are going down. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) hw->shutting_down = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) del_timer(&hw->setup_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) /* Prevent the hardware from sending any more interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) do_close_hardware(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) void ipwireless_hardware_free(struct ipw_hardware *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) struct ipw_rx_packet *rp, *rq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) struct ipw_tx_packet *tp, *tq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) ipwireless_stop_interrupts(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) flush_work(&hw->work_rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) for (i = 0; i < NL_NUM_OF_ADDRESSES; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) kfree(hw->packet_assembler[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) for (i = 0; i < NL_NUM_OF_PRIORITIES; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) list_for_each_entry_safe(tp, tq, &hw->tx_queue[i], queue) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) list_del(&tp->queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) kfree(tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) list_for_each_entry_safe(rp, rq, &hw->rx_queue, queue) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) list_del(&rp->queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) kfree(rp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) list_for_each_entry_safe(rp, rq, &hw->rx_pool, queue) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) list_del(&rp->queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) kfree(rp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) kfree(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) * Associate the specified network with this hardware, so it will receive events
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) * from it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) void ipwireless_associate_network(struct ipw_hardware *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) struct ipw_network *network)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) hw->network = network;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) }