Commit c4e84bde authored by Ron Mercer's avatar Ron Mercer Committed by Jeff Garzik

qlge: New Qlogic 10Gb Ethernet Driver.

Signed-off-by: default avatarRon Mercer <ron.mercer@qlogic.com>
Signed-off-by: default avatarJeff Garzik <jgarzik@redhat.com>
parent 95252236
Copyright (c) 2003-2008 QLogic Corporation
QLogic Linux Networking HBA Driver
This program includes a device driver for Linux 2.6 that may be
distributed with QLogic hardware specific firmware binary file.
You may modify and redistribute the device driver code under the
GNU General Public License as published by the Free Software
Foundation (version 2 or a later version).
You may redistribute the hardware specific firmware binary file
under the following terms:
1. Redistribution of source code (only if applicable),
must retain the above copyright notice, this list of
conditions and the following disclaimer.
2. Redistribution in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
3. The name of QLogic Corporation may not be used to
endorse or promote products derived from this software
without specific prior written permission
REGARDLESS OF WHAT LICENSING MECHANISM IS USED OR APPLICABLE,
THIS PROGRAM IS PROVIDED BY QLOGIC CORPORATION "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
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.
USER ACKNOWLEDGES AND AGREES THAT USE OF THIS PROGRAM WILL NOT
CREATE OR GIVE GROUNDS FOR A LICENSE BY IMPLICATION, ESTOPPEL, OR
OTHERWISE IN ANY INTELLECTUAL PROPERTY RIGHTS (PATENT, COPYRIGHT,
TRADE SECRET, MASK WORK, OR OTHER PROPRIETARY RIGHT) EMBODIED IN
ANY OTHER QLOGIC HARDWARE OR SOFTWARE EITHER SOLELY OR IN
COMBINATION WITH THIS PROGRAM.
......@@ -3396,6 +3396,13 @@ M: linux-driver@qlogic.com
L: netdev@vger.kernel.org
S: Supported
QLOGIC QLGE 10Gb ETHERNET DRIVER
P: Ron Mercer
M: linux-driver@qlogic.com
M: ron.mercer@qlogic.com
L: netdev@vger.kernel.org
S: Supported
QNX4 FILESYSTEM
P: Anders Larsen
M: al@alarsen.net
......
......@@ -2526,6 +2526,15 @@ config BNX2X
To compile this driver as a module, choose M here: the module
will be called bnx2x. This is recommended.
config QLGE
tristate "QLogic QLGE 10Gb Ethernet Driver Support"
depends on PCI
help
This driver supports QLogic ISP8XXX 10Gb Ethernet cards.
To compile this driver as a module, choose M here: the module
will be called qlge.
source "drivers/net/sfc/Kconfig"
endif # NETDEV_10000
......
......@@ -131,6 +131,7 @@ obj-$(CONFIG_AX88796) += ax88796.o
obj-$(CONFIG_TSI108_ETH) += tsi108_eth.o
obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o
obj-$(CONFIG_QLA3XXX) += qla3xxx.o
obj-$(CONFIG_QLGE) += qlge/
obj-$(CONFIG_PPP) += ppp_generic.o
obj-$(CONFIG_PPP_ASYNC) += ppp_async.o
......
#
# Makefile for the Qlogic 10GbE PCI Express ethernet driver
#
obj-$(CONFIG_QLGE) += qlge.o
qlge-objs := qlge_main.o qlge_dbg.o qlge_mpi.o qlge_ethtool.o
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#include "qlge.h"
static int ql_read_mbox_reg(struct ql_adapter *qdev, u32 reg, u32 *data)
{
int status;
/* wait for reg to come ready */
status = ql_wait_reg_rdy(qdev, PROC_ADDR, PROC_ADDR_RDY, PROC_ADDR_ERR);
if (status)
goto exit;
/* set up for reg read */
ql_write32(qdev, PROC_ADDR, reg | PROC_ADDR_R);
/* wait for reg to come ready */
status = ql_wait_reg_rdy(qdev, PROC_ADDR, PROC_ADDR_RDY, PROC_ADDR_ERR);
if (status)
goto exit;
/* get the data */
*data = ql_read32(qdev, PROC_DATA);
exit:
return status;
}
int ql_get_mb_sts(struct ql_adapter *qdev, struct mbox_params *mbcp)
{
int i, status;
status = ql_sem_spinlock(qdev, SEM_PROC_REG_MASK);
if (status)
return -EBUSY;
for (i = 0; i < mbcp->out_count; i++) {
status =
ql_read_mbox_reg(qdev, qdev->mailbox_out + i,
&mbcp->mbox_out[i]);
if (status) {
QPRINTK(qdev, DRV, ERR, "Failed mailbox read.\n");
break;
}
}
ql_sem_unlock(qdev, SEM_PROC_REG_MASK); /* does flush too */
return status;
}
static void ql_link_up(struct ql_adapter *qdev, struct mbox_params *mbcp)
{
mbcp->out_count = 2;
if (ql_get_mb_sts(qdev, mbcp))
goto exit;
qdev->link_status = mbcp->mbox_out[1];
QPRINTK(qdev, DRV, ERR, "Link Up.\n");
QPRINTK(qdev, DRV, INFO, "Link Status = 0x%.08x.\n", mbcp->mbox_out[1]);
if (!netif_carrier_ok(qdev->ndev)) {
QPRINTK(qdev, LINK, INFO, "Link is Up.\n");
netif_carrier_on(qdev->ndev);
netif_wake_queue(qdev->ndev);
}
exit:
/* Clear the MPI firmware status. */
ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT);
}
static void ql_link_down(struct ql_adapter *qdev, struct mbox_params *mbcp)
{
mbcp->out_count = 3;
if (ql_get_mb_sts(qdev, mbcp)) {
QPRINTK(qdev, DRV, ERR, "Firmware did not initialize!\n");
goto exit;
}
if (netif_carrier_ok(qdev->ndev)) {
QPRINTK(qdev, LINK, INFO, "Link is Down.\n");
netif_carrier_off(qdev->ndev);
netif_stop_queue(qdev->ndev);
}
QPRINTK(qdev, DRV, ERR, "Link Down.\n");
QPRINTK(qdev, DRV, ERR, "Link Status = 0x%.08x.\n", mbcp->mbox_out[1]);
exit:
/* Clear the MPI firmware status. */
ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT);
}
static void ql_init_fw_done(struct ql_adapter *qdev, struct mbox_params *mbcp)
{
mbcp->out_count = 2;
if (ql_get_mb_sts(qdev, mbcp)) {
QPRINTK(qdev, DRV, ERR, "Firmware did not initialize!\n");
goto exit;
}
QPRINTK(qdev, DRV, ERR, "Firmware initialized!\n");
QPRINTK(qdev, DRV, ERR, "Firmware status = 0x%.08x.\n",
mbcp->mbox_out[0]);
QPRINTK(qdev, DRV, ERR, "Firmware Revision = 0x%.08x.\n",
mbcp->mbox_out[1]);
exit:
/* Clear the MPI firmware status. */
ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT);
}
void ql_mpi_work(struct work_struct *work)
{
struct ql_adapter *qdev =
container_of(work, struct ql_adapter, mpi_work.work);
struct mbox_params mbc;
struct mbox_params *mbcp = &mbc;
mbcp->out_count = 1;
while (ql_read32(qdev, STS) & STS_PI) {
if (ql_get_mb_sts(qdev, mbcp)) {
QPRINTK(qdev, DRV, ERR,
"Could not read MPI, resetting ASIC!\n");
ql_queue_asic_error(qdev);
}
switch (mbcp->mbox_out[0]) {
case AEN_LINK_UP:
ql_link_up(qdev, mbcp);
break;
case AEN_LINK_DOWN:
ql_link_down(qdev, mbcp);
break;
case AEN_FW_INIT_DONE:
ql_init_fw_done(qdev, mbcp);
break;
case MB_CMD_STS_GOOD:
break;
case AEN_FW_INIT_FAIL:
case AEN_SYS_ERR:
case MB_CMD_STS_ERR:
ql_queue_fw_error(qdev);
default:
/* Clear the MPI firmware status. */
ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT);
break;
}
}
ql_enable_completion_interrupt(qdev, 0);
}
void ql_mpi_reset_work(struct work_struct *work)
{
struct ql_adapter *qdev =
container_of(work, struct ql_adapter, mpi_reset_work.work);
QPRINTK(qdev, DRV, ERR,
"Enter, qdev = %p..\n", qdev);
ql_write32(qdev, CSR, CSR_CMD_SET_RST);
msleep(50);
ql_write32(qdev, CSR, CSR_CMD_CLR_RST);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment