qlge_gld.c revision 4aa4baabcbf85382c40c826cabf97d046ba28c89
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 QLogic Corporation. All rights reserved.
*/
#include <qlge.h>
/*
* GLDv3 functions prototypes
*/
static int ql_m_start(void *);
static void ql_m_stop(void *);
static int ql_m_setpromiscuous(void *, boolean_t);
static int ql_m_unicst(void *, const uint8_t *);
const void *);
void *, uint_t *);
static mac_callbacks_t ql_m_callbacks = {
NULL,
NULL,
NULL,
NULL,
};
{"_adv_pause_mode", MAC_PROP_PERM_RW}
};
#define QLGE_MAX_PRIV_PROPS \
(sizeof (qlge_priv_prop) / sizeof (mac_priv_prop_t))
/*
* This function starts the driver
*/
static int
ql_m_start(void *arg)
{
/*
* reset chip, re-initialize everything but do not
* re-allocate memory
*/
return (ECANCELED);
}
/*
* Write default ethernet address to chip register Mac
* Address slot 0 and Enable Primary Mac Function.
*/
(void) ql_unicst_set(qlge,
(void) ql_do_start(qlge);
return (0);
}
/*
* This function stops the driver
*/
static void
{
return;
}
(void) ql_do_stop(qlge);
}
/*
* Add or remove a multicast address
*/
static int
{
int ret = DDI_SUCCESS;
return (ECANCELED);
}
return (ECANCELED);
}
if (add) {
} else {
}
}
/*
* Enable or disable promiscuous mode
*/
static int
{
int mode;
return (ECANCELED);
}
/* enable reception of all packets on the medium, */
if (on) {
mode = 1;
} else {
mode = 0;
}
return (DDI_SUCCESS);
}
static int
{
int i;
return (ECANCELED);
}
/* these stats are maintained in software */
switch (stat) {
case MAC_STAT_IFSPEED /* 1000 */ :
}
break;
case MAC_STAT_MULTIRCV:
break;
case MAC_STAT_BRDCSTRCV:
break;
case MAC_STAT_MULTIXMT:
for (i = 0; i < qlge->tx_ring_count; i++) {
}
break;
case MAC_STAT_BRDCSTXMT:
for (i = 0; i < qlge->tx_ring_count; i++) {
}
break;
case MAC_STAT_NORCVBUF:
break;
case MAC_STAT_IERRORS:
break;
case MAC_STAT_OBYTES:
for (i = 0; i < qlge->tx_ring_count; i++) {
}
break;
case MAC_STAT_OPACKETS:
for (i = 0; i < qlge->tx_ring_count; i++) {
}
break;
case ETHER_STAT_DEFER_XMTS:
for (i = 0; i < qlge->tx_ring_count; i++) {
}
break;
case MAC_STAT_OERRORS:
for (i = 0; i < qlge->tx_ring_count; i++) {
}
break;
case MAC_STAT_RBYTES:
for (i = 0; i < qlge->rx_ring_count; i++) {
}
break;
case MAC_STAT_IPACKETS:
for (i = 0; i < qlge->rx_ring_count; i++) {
}
break;
case ETHER_STAT_FCS_ERRORS:
for (i = 0; i < qlge->rx_ring_count; i++) {
}
break;
cur_stats->frame_too_long = 0;
for (i = 0; i < qlge->rx_ring_count; i++) {
}
break;
case ETHER_STAT_XCVR_INUSE:
val = XCVR_1000X;
break;
case ETHER_STAT_JABBER_ERRORS:
DDI_SUCCESS) {
break;
}
&val32);
break;
case ETHER_STAT_LINK_DUPLEX:
else
break;
/* statics saved in hw */
case ETHER_STAT_MACRCV_ERRORS:
val = 0;
DDI_SUCCESS) {
break;
}
&val32);
&val32);
&val32);
&val32);
break;
default:
return (ENOTSUP);
}
return (0);
}
/*
* Set the physical network address
*/
static int
{
int status;
if (status != DDI_SUCCESS)
return (EIO);
}
/*
* Set default MAC address
* Each function has a total of 128 mac address, function0: 0~127,
* function1 128~254 etc or func_number *128 + n (0~127), but
* we only support one MAC address, so its address is
* func_number*128+0
*/
static int
{
int status;
return (ECANCELED);
}
/* Set Mac Address to slot 0 and Enable Primary Mac Function */
return (status);
}
/*
* ql_m_tx is used only for sending data packets into ethernet wire.
*/
static mblk_t *
{
int rval;
goto tx_exit;
}
/*
* Always send this packet through tx ring 0 for now.
* Will use multiple tx rings when Crossbow is supported
*/
goto tx_exit;
}
/* we must try to send all */
/*
* if number of available slots is less than a threshold,
* then quit
*/
rval = DDI_FAILURE;
/*
* If we return the buffer back we are expected to
* call mac_tx_ring_update() when
* resources are available
*/
break;
}
if (rval != DDI_SUCCESS) {
break;
}
tx_count++;
}
/*
* After all msg blocks are mapped or copied to tx buffer,
* trigger the hardware to send the msg!
*/
if (tx_count > 0) {
}
return (mp);
}
static void
{
/*
* Validate the command before bothering with the mutex...
*/
return;
}
switch (cmd) {
default:
return;
case QLA_PCI_STATUS:
case QLA_WRITE_REG:
case QLA_READ_PCI_REG:
case QLA_WRITE_PCI_REG:
case QLA_GET_DBGLEAVEL:
case QLA_SET_DBGLEAVEL:
case QLA_MANUAL_READ_FLASH:
case QLA_MANUAL_WRITE_FLASH:
case QLA_GET_BINARY_CORE_DUMP:
case QLA_SUPPORTED_DUMP_TYPES:
case QLA_READ_FLASH:
case QLA_WRITE_FLASH:
case QLA_READ_VPD:
case QLA_GET_PROP:
case QLA_SHOW_REGION:
case QLA_LIST_ADAPTER_INFO:
case QLA_READ_FW_IMAGE:
case QLA_CONTINUE_COPY_IN:
case QLA_CONTINUE_COPY_OUT:
case QLA_SOFT_RESET:
break;
case LB_GET_INFO_SIZE:
case LB_GET_INFO:
case LB_GET_MODE:
/* FALLTHRU */
case LB_SET_MODE:
break;
}
if (need_privilege) {
/*
* Check for specific net_config privilege
*/
if (err != 0) {
return;
}
}
/*
* Implement ioctl
*/
switch (cmd) {
case QLA_PCI_STATUS:
case QLA_WRITE_REG:
case QLA_READ_PCI_REG:
case QLA_WRITE_PCI_REG:
case QLA_GET_DBGLEAVEL:
case QLA_SET_DBGLEAVEL:
case QLA_MANUAL_READ_FLASH:
case QLA_MANUAL_WRITE_FLASH:
case QLA_GET_BINARY_CORE_DUMP:
case QLA_SUPPORTED_DUMP_TYPES:
case QLA_READ_FLASH:
case QLA_WRITE_FLASH:
case QLA_READ_VPD:
case QLA_GET_PROP:
case QLA_SHOW_REGION:
case QLA_LIST_ADAPTER_INFO:
case QLA_READ_FW_IMAGE:
case QLA_CONTINUE_COPY_IN:
case QLA_CONTINUE_COPY_OUT:
case QLA_SOFT_RESET:
break;
case LB_GET_INFO_SIZE:
case LB_GET_INFO:
case LB_GET_MODE:
case LB_SET_MODE:
break;
default:
break;
}
/*
* Decide how to reply
*/
switch (status) {
default:
case IOC_INVAL:
/*
* Error, reply with a NAK and EINVAL or the specified error
*/
break;
case IOC_DONE:
/*
* OK, reply already sent
*/
break;
case IOC_ACK:
/*
* OK, reply with an ACK
*/
break;
case IOC_REPLY:
/*
* OK, send prepared reply as ACK or NAK
*/
break;
}
}
/* ARGSUSED */
static int
const void *pr_val)
{
int err = 0;
long result;
if (result > PAUSE_MODE_PER_PRIORITY ||
}
}
return (err);
}
return (ENOTSUP);
}
static int
{
err = 0;
goto done;
}
done:
if (err == 0) {
}
return (err);
}
/*
*/
/* ARGSUSED */
static int
{
int err = 0;
return (ECANCELED);
}
switch (pr_num) {
case MAC_PROP_MTU:
err = 0;
break;
}
break;
}
/*
* do not change on the fly, allow only before
* driver is started or stopped
*/
"driver busy, mac_flags %d", __func__,
break;
}
if (err == 0) {
/* EMPTY */
new_mtu));
}
break;
case MAC_PROP_PRIVATE:
pr_val);
break;
default:
break;
}
return (err);
}
/* ARGSUSED */
static int
{
int err = 0;
goto out;
}
if (pr_valsize == 0) {
goto out;
}
/* mostly read only */
switch (pr_num) {
case MAC_PROP_DUPLEX:
if (pr_valsize < sizeof (link_duplex_t)) {
goto out;
}
else
sizeof (link_duplex_t));
break;
case MAC_PROP_SPEED:
if (pr_valsize < sizeof (speed)) {
goto out;
}
break;
case MAC_PROP_STATUS:
if (pr_valsize < sizeof (link_state_t)) {
goto out;
}
else
sizeof (link_state_t));
break;
case MAC_PROP_PRIVATE:
pr_valsize, pr_val);
break;
default:
}
out:
return (err);
}
/* ARGSUSED */
static boolean_t
{
switch (cap) {
case MAC_CAPAB_HCKSUM:
}
}
}
}
break;
case MAC_CAPAB_LSO: {
}
break;
}
default:
return (B_FALSE);
}
return (ret);
}
void
{
/* This is the mac address from flash to be used by the port */
}