/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Copyright (c) 2004, 2005
* Damien Bergamini <damien.bergamini@free.fr>. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice unmodified, this list of conditions, and the following
* disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Intel Wireless PRO/2200 mini-PCI adapter driver
* ipw2200_hw.c is used t handle hardware operations and firmware operations.
*/
#include <sys/byteorder.h>
#include "ipw2200.h"
#include "ipw2200_impl.h"
/*
* Hardware related operations
*/
{
}
{
}
{
}
void
{
}
void
{
}
void
{
}
void
{
}
{
}
{
}
{
}
void
{
}
void
{
}
void
{
}
void
{
}
{
int n;
/*
* According to i2c bus protocol
*/
/* clock */
ipw2200_rom_control(sc, 0);
/* start bit */
/* read opcode */
/*
* address, totally 8 bits, defined by hardware, push from MSB to LSB
*/
for (n = 7; n >= 0; n--) {
}
/*
* data, totally 16 bits, defined by hardware, push from MSB to LSB
*/
val = 0;
for (n = 15; n >= 0; n--) {
<< n;
}
ipw2200_rom_control(sc, 0);
/* clear chip select and clock */
ipw2200_rom_control(sc, 0);
}
/*
* Firmware related operations
*/
/*
* These firwares were issued by Intel as binaries which need to be
* loaded to hardware when card is initiated, or when fatal error
* happened, or when the chip need be reset.
*/
#include "fw-ipw2200/ipw-2.4-boot.hex"
};
#include "fw-ipw2200/ipw-2.4-bss_ucode.hex"
};
#include "fw-ipw2200/ipw-2.4-bss.hex"
};
#pragma pack(1)
struct header {
};
#pragma pack()
int
{
"ipw2200_cache_firmware(): enter\n"));
/* boot code */
sizeof (ipw2200_boot_bin) - sizeof (struct header);
/* ucode */
/* firmware */
"ipw2200_cache_firmware(): boot=%u,uc=%u,fw=%u\n",
"ipw2200_cache_firmware(): exit\n"));
return (DDI_SUCCESS);
}
/*
* If user-land firmware loading is supported, this routine will
* free kernel memory, when sc->sc_fw.bin_base & sc->sc_fw.bin_size
* are not empty
*/
int
{
return (DDI_SUCCESS);
}
/*
* the following routines load code onto ipw2200 hardware
*/
int
{
int ntries, i;
uint16_t *w;
break;
drv_usecwait(10);
}
if (ntries == 5) {
"ipw2200_load_uc(): timeout waiting for master"));
return (DDI_FAILURE);
}
drv_usecwait(5000);
drv_usecwait(5000);
drv_usecwait(1000);
drv_usecwait(1000);
drv_usecwait(1000);
drv_usecwait(1000);
/*
* try many times to wait the upload is ready, 2000times
*/
if (val & 1)
break;
}
if (ntries == 2000) {
"ipw2200_load_uc(): timeout waiting for ucode init.\n"));
return (DDI_FAILURE);
}
for (i = 0; i < 7; i++)
return (DDI_SUCCESS);
}
int
{
p = buf;
cnt = 0;
if (err != DDI_SUCCESS)
goto fail0;
off = 0;
while (p < end) {
v = p;
p += len;
while (len > 0) {
/*
* if no DMA region is available, allocate a new one
*/
cnt++;
if (cnt >= MAX_DR_NUM) {
"ipw2200_load_fw(): "
"maximum %d DRs is reached\n",
cnt));
cnt--; /* only free alloced DMA */
goto fail1;
}
if (err != DDI_SUCCESS) {
cnt--; /* only free alloced DMA */
goto fail1;
}
off = 0;
}
/*
* write a command
*/
v += mlen;
}
}
"ipw2200_load_fw(): sentinel=%x\n", sentinel));
break;
drv_usecwait(100);
}
if (ntries == 400) {
"ipw2200_load_fw(): timeout processing command blocks\n"));
goto fail1;
}
/*
* enable all interrupts
*/
/*
* tell the adapter to initialize the firmware,
* just simply set it to 0
*/
/*
* wait for interrupt to notify fw initialization is done
*/
/*
* There is an enhancement! we just change from 1s to 5s
*/
TR_CLOCK_TICK) < 0)
break;
}
"ipw2200_load_fw(): firmware(%u) load failed!", size));
goto fail1;
}
for (i = 0; i <= cnt; i++)
ipw2200_dma_region_free(&dr[i]);
return (DDI_SUCCESS);
"ipw2200_load_fw(): DMA allocation failed, cnt=%d\n", cnt));
for (i = 0; i <= cnt; i++)
ipw2200_dma_region_free(&dr[i]);
return (DDI_FAILURE);
}