2009-03-11 23:32:03 -07:00
/*
2011-03-16 08:20:46 +00:00
* Copyright ( C ) 2005 - 2011 Emulex
2009-03-11 23:32:03 -07:00
* All rights reserved .
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation . The full GNU General
* Public License is included in this distribution in the file called COPYING .
*
* Contact Information :
2011-03-16 08:20:46 +00:00
* linux - drivers @ emulex . com
2009-03-11 23:32:03 -07:00
*
2011-03-16 08:20:46 +00:00
* Emulex
* 3333 Susan Street
* Costa Mesa , CA 92626
2009-03-11 23:32:03 -07:00
*/
# include "be.h"
2009-07-27 22:52:03 +00:00
# include "be_cmds.h"
2009-03-11 23:32:03 -07:00
2011-02-20 11:42:07 +00:00
/* Must be a power of 2 or else MODULO will BUG_ON */
static int be_get_temp_freq = 32 ;
2009-07-27 22:52:03 +00:00
static void be_mcc_notify ( struct be_adapter * adapter )
2009-06-18 00:02:59 +00:00
{
2009-07-27 22:52:03 +00:00
struct be_queue_info * mccq = & adapter - > mcc_obj . q ;
2009-06-18 00:02:59 +00:00
u32 val = 0 ;
2011-02-11 13:38:17 +00:00
if ( adapter - > eeh_err ) {
dev_info ( & adapter - > pdev - > dev ,
" Error in Card Detected! Cannot issue commands \n " ) ;
return ;
}
2009-06-18 00:02:59 +00:00
val | = mccq - > id & DB_MCCQ_RING_ID_MASK ;
val | = 1 < < DB_MCCQ_NUM_POSTED_SHIFT ;
2010-06-29 00:11:17 +00:00
wmb ( ) ;
2009-07-27 22:52:03 +00:00
iowrite32 ( val , adapter - > db + DB_MCCQ_OFFSET ) ;
2009-06-18 00:02:59 +00:00
}
/* To check if valid bit is set, check the entire word as we don't know
* the endianness of the data ( old entry is host endian while a new entry is
* little endian ) */
2009-07-27 22:53:10 +00:00
static inline bool be_mcc_compl_is_new ( struct be_mcc_compl * compl )
2009-06-18 00:02:59 +00:00
{
if ( compl - > flags ! = 0 ) {
compl - > flags = le32_to_cpu ( compl - > flags ) ;
BUG_ON ( ( compl - > flags & CQE_FLAGS_VALID_MASK ) = = 0 ) ;
return true ;
} else {
return false ;
}
}
/* Need to reset the entire word that houses the valid bit */
2009-07-27 22:53:10 +00:00
static inline void be_mcc_compl_use ( struct be_mcc_compl * compl )
2009-06-18 00:02:59 +00:00
{
compl - > flags = 0 ;
}
2009-07-27 22:52:03 +00:00
static int be_mcc_compl_process ( struct be_adapter * adapter ,
2009-07-27 22:53:10 +00:00
struct be_mcc_compl * compl )
2009-06-18 00:02:59 +00:00
{
u16 compl_status , extd_status ;
/* Just swap the status to host endian; mcc tag is opaquely copied
* from mcc_wrb */
be_dws_le_to_cpu ( compl , 4 ) ;
compl_status = ( compl - > status > > CQE_STATUS_COMPL_SHIFT ) &
CQE_STATUS_COMPL_MASK ;
2010-05-25 16:16:32 -07:00
2011-05-16 07:36:59 +00:00
if ( ( ( compl - > tag0 = = OPCODE_COMMON_WRITE_FLASHROM ) | |
( compl - > tag0 = = OPCODE_COMMON_WRITE_OBJECT ) ) & &
2010-05-25 16:16:32 -07:00
( compl - > tag1 = = CMD_SUBSYSTEM_COMMON ) ) {
adapter - > flash_status = compl_status ;
complete ( & adapter - > flash_compl ) ;
}
2009-09-17 10:30:13 -07:00
if ( compl_status = = MCC_STATUS_SUCCESS ) {
2011-05-16 07:36:35 +00:00
if ( ( ( compl - > tag0 = = OPCODE_ETH_GET_STATISTICS ) | |
( compl - > tag0 = = OPCODE_ETH_GET_PPORT_STATS ) ) & &
2011-04-19 12:11:02 +00:00
( compl - > tag1 = = CMD_SUBSYSTEM_ETH ) ) {
2011-05-16 07:36:18 +00:00
if ( adapter - > generation = = BE_GEN3 ) {
2011-05-16 07:36:35 +00:00
if ( lancer_chip ( adapter ) ) {
struct lancer_cmd_resp_pport_stats
* resp = adapter - > stats_cmd . va ;
be_dws_le_to_cpu ( & resp - > pport_stats ,
sizeof ( resp - > pport_stats ) ) ;
} else {
struct be_cmd_resp_get_stats_v1 * resp =
2011-05-16 07:36:18 +00:00
adapter - > stats_cmd . va ;
be_dws_le_to_cpu ( & resp - > hw_stats ,
sizeof ( resp - > hw_stats ) ) ;
2011-05-16 07:36:35 +00:00
}
2011-05-16 07:36:18 +00:00
} else {
struct be_cmd_resp_get_stats_v0 * resp =
adapter - > stats_cmd . va ;
be_dws_le_to_cpu ( & resp - > hw_stats ,
sizeof ( resp - > hw_stats ) ) ;
}
be_parse_stats ( adapter ) ;
2009-09-17 10:30:13 -07:00
netdev_stats_update ( adapter ) ;
2011-02-20 11:41:39 +00:00
adapter - > stats_cmd_sent = false ;
2009-09-17 10:30:13 -07:00
}
2011-06-29 23:32:56 +00:00
} else {
if ( compl_status = = MCC_STATUS_NOT_SUPPORTED | |
compl_status = = MCC_STATUS_ILLEGAL_REQUEST )
goto done ;
if ( compl_status = = MCC_STATUS_UNAUTHORIZED_REQUEST ) {
dev_warn ( & adapter - > pdev - > dev , " This domain(VM) is not "
" permitted to execute this cmd (opcode %d) \n " ,
compl - > tag0 ) ;
} else {
extd_status = ( compl - > status > > CQE_STATUS_EXTD_SHIFT ) &
CQE_STATUS_EXTD_MASK ;
dev_err ( & adapter - > pdev - > dev , " Cmd (opcode %d) failed: "
" status %d, extd-status %d \n " ,
compl - > tag0 , compl_status , extd_status ) ;
}
2009-06-18 00:02:59 +00:00
}
2011-06-29 23:32:56 +00:00
done :
2009-09-17 10:30:13 -07:00
return compl_status ;
2009-06-18 00:02:59 +00:00
}
2009-06-18 00:10:27 +00:00
/* Link state evt is a string of bytes; no need for endian swapping */
2009-07-27 22:52:03 +00:00
static void be_async_link_state_process ( struct be_adapter * adapter ,
2009-06-18 00:10:27 +00:00
struct be_async_event_link_state * evt )
{
2009-07-27 22:52:03 +00:00
be_link_status_update ( adapter ,
evt - > port_link_status = = ASYNC_EVENT_LINK_UP ) ;
2009-06-18 00:10:27 +00:00
}
2010-10-21 07:11:14 -07:00
/* Grp5 CoS Priority evt */
static void be_async_grp5_cos_priority_process ( struct be_adapter * adapter ,
struct be_async_event_grp5_cos_priority * evt )
{
if ( evt - > valid ) {
adapter - > vlan_prio_bmap = evt - > available_priority_bmap ;
2011-02-11 13:37:25 +00:00
adapter - > recommended_prio & = ~ VLAN_PRIO_MASK ;
2010-10-21 07:11:14 -07:00
adapter - > recommended_prio =
evt - > reco_default_priority < < VLAN_PRIO_SHIFT ;
}
}
/* Grp5 QOS Speed evt */
static void be_async_grp5_qos_speed_process ( struct be_adapter * adapter ,
struct be_async_event_grp5_qos_link_speed * evt )
{
if ( evt - > physical_port = = adapter - > port_num ) {
/* qos_link_speed is in units of 10 Mbps */
adapter - > link_speed = evt - > qos_link_speed * 10 ;
}
}
2011-02-20 11:41:53 +00:00
/*Grp5 PVID evt*/
static void be_async_grp5_pvid_state_process ( struct be_adapter * adapter ,
struct be_async_event_grp5_pvid_state * evt )
{
if ( evt - > enabled )
2011-05-04 22:40:46 +00:00
adapter - > pvid = le16_to_cpu ( evt - > tag ) ;
2011-02-20 11:41:53 +00:00
else
adapter - > pvid = 0 ;
}
2010-10-21 07:11:14 -07:00
static void be_async_grp5_evt_process ( struct be_adapter * adapter ,
u32 trailer , struct be_mcc_compl * evt )
{
u8 event_type = 0 ;
event_type = ( trailer > > ASYNC_TRAILER_EVENT_TYPE_SHIFT ) &
ASYNC_TRAILER_EVENT_TYPE_MASK ;
switch ( event_type ) {
case ASYNC_EVENT_COS_PRIORITY :
be_async_grp5_cos_priority_process ( adapter ,
( struct be_async_event_grp5_cos_priority * ) evt ) ;
break ;
case ASYNC_EVENT_QOS_SPEED :
be_async_grp5_qos_speed_process ( adapter ,
( struct be_async_event_grp5_qos_link_speed * ) evt ) ;
break ;
2011-02-20 11:41:53 +00:00
case ASYNC_EVENT_PVID_STATE :
be_async_grp5_pvid_state_process ( adapter ,
( struct be_async_event_grp5_pvid_state * ) evt ) ;
break ;
2010-10-21 07:11:14 -07:00
default :
dev_warn ( & adapter - > pdev - > dev , " Unknown grp5 event! \n " ) ;
break ;
}
}
2009-06-18 00:10:27 +00:00
static inline bool is_link_state_evt ( u32 trailer )
{
2010-09-23 05:40:09 +00:00
return ( ( trailer > > ASYNC_TRAILER_EVENT_CODE_SHIFT ) &
2009-06-18 00:10:27 +00:00
ASYNC_TRAILER_EVENT_CODE_MASK ) = =
2010-09-23 05:40:09 +00:00
ASYNC_EVENT_CODE_LINK_STATE ;
2009-06-18 00:10:27 +00:00
}
2009-06-18 00:02:59 +00:00
2010-10-21 07:11:14 -07:00
static inline bool is_grp5_evt ( u32 trailer )
{
return ( ( ( trailer > > ASYNC_TRAILER_EVENT_CODE_SHIFT ) &
ASYNC_TRAILER_EVENT_CODE_MASK ) = =
ASYNC_EVENT_CODE_GRP_5 ) ;
}
2009-07-27 22:53:10 +00:00
static struct be_mcc_compl * be_mcc_compl_get ( struct be_adapter * adapter )
2009-06-18 00:02:59 +00:00
{
2009-07-27 22:52:03 +00:00
struct be_queue_info * mcc_cq = & adapter - > mcc_obj . cq ;
2009-07-27 22:53:10 +00:00
struct be_mcc_compl * compl = queue_tail_node ( mcc_cq ) ;
2009-06-18 00:02:59 +00:00
if ( be_mcc_compl_is_new ( compl ) ) {
queue_tail_inc ( mcc_cq ) ;
return compl ;
}
return NULL ;
}
2010-02-17 01:35:11 +00:00
void be_async_mcc_enable ( struct be_adapter * adapter )
{
spin_lock_bh ( & adapter - > mcc_cq_lock ) ;
be_cq_notify ( adapter , adapter - > mcc_obj . cq . id , true , 0 ) ;
adapter - > mcc_obj . rearm_cq = true ;
spin_unlock_bh ( & adapter - > mcc_cq_lock ) ;
}
void be_async_mcc_disable ( struct be_adapter * adapter )
{
adapter - > mcc_obj . rearm_cq = false ;
}
2010-03-02 03:56:39 -08:00
int be_process_mcc ( struct be_adapter * adapter , int * status )
2009-06-18 00:02:59 +00:00
{
2009-07-27 22:53:10 +00:00
struct be_mcc_compl * compl ;
2010-03-02 03:56:39 -08:00
int num = 0 ;
2010-02-17 01:35:11 +00:00
struct be_mcc_obj * mcc_obj = & adapter - > mcc_obj ;
2009-06-18 00:02:59 +00:00
2009-07-27 22:52:03 +00:00
spin_lock_bh ( & adapter - > mcc_cq_lock ) ;
while ( ( compl = be_mcc_compl_get ( adapter ) ) ) {
2009-06-18 00:10:27 +00:00
if ( compl - > flags & CQE_FLAGS_ASYNC_MASK ) {
/* Interpret flags as an async trailer */
2010-09-03 06:24:13 +00:00
if ( is_link_state_evt ( compl - > flags ) )
be_async_link_state_process ( adapter ,
2009-06-18 00:10:27 +00:00
( struct be_async_event_link_state * ) compl ) ;
2010-10-21 07:11:14 -07:00
else if ( is_grp5_evt ( compl - > flags ) )
be_async_grp5_evt_process ( adapter ,
compl - > flags , compl ) ;
2009-09-17 10:30:13 -07:00
} else if ( compl - > flags & CQE_FLAGS_COMPLETED_MASK ) {
2010-03-02 03:56:39 -08:00
* status = be_mcc_compl_process ( adapter , compl ) ;
2010-02-17 01:35:11 +00:00
atomic_dec ( & mcc_obj - > q . used ) ;
2009-06-18 00:02:59 +00:00
}
be_mcc_compl_use ( compl ) ;
num + + ;
}
2009-09-17 10:30:13 -07:00
2009-07-27 22:52:03 +00:00
spin_unlock_bh ( & adapter - > mcc_cq_lock ) ;
2010-03-02 03:56:39 -08:00
return num ;
2009-06-18 00:02:59 +00:00
}
2009-06-18 00:05:54 +00:00
/* Wait till no more pending mcc requests are present */
2009-09-17 10:30:13 -07:00
static int be_mcc_wait_compl ( struct be_adapter * adapter )
2009-06-18 00:05:54 +00:00
{
2009-09-17 10:30:13 -07:00
# define mcc_timeout 120000 /* 12s timeout */
2010-03-02 03:56:39 -08:00
int i , num , status = 0 ;
struct be_mcc_obj * mcc_obj = & adapter - > mcc_obj ;
2011-02-11 13:38:17 +00:00
if ( adapter - > eeh_err )
return - EIO ;
2009-06-18 00:05:54 +00:00
for ( i = 0 ; i < mcc_timeout ; i + + ) {
2010-03-02 03:56:39 -08:00
num = be_process_mcc ( adapter , & status ) ;
if ( num )
be_cq_notify ( adapter , mcc_obj - > cq . id ,
mcc_obj - > rearm_cq , num ) ;
2009-09-17 10:30:13 -07:00
2010-03-02 03:56:39 -08:00
if ( atomic_read ( & mcc_obj - > q . used ) = = 0 )
2009-06-18 00:05:54 +00:00
break ;
udelay ( 100 ) ;
}
2009-09-17 10:30:13 -07:00
if ( i = = mcc_timeout ) {
2009-07-27 22:52:56 +00:00
dev_err ( & adapter - > pdev - > dev , " mccq poll timed out \n " ) ;
2009-09-17 10:30:13 -07:00
return - 1 ;
}
2010-03-02 03:56:39 -08:00
return status ;
2009-06-18 00:05:54 +00:00
}
/* Notify MCC requests and wait for completion */
2009-09-17 10:30:13 -07:00
static int be_mcc_notify_wait ( struct be_adapter * adapter )
2009-06-18 00:05:54 +00:00
{
2009-07-27 22:52:03 +00:00
be_mcc_notify ( adapter ) ;
2009-09-17 10:30:13 -07:00
return be_mcc_wait_compl ( adapter ) ;
2009-06-18 00:05:54 +00:00
}
2009-07-27 22:52:56 +00:00
static int be_mbox_db_ready_wait ( struct be_adapter * adapter , void __iomem * db )
2009-03-11 23:32:03 -07:00
{
2010-05-30 23:34:14 +00:00
int msecs = 0 ;
2009-03-11 23:32:03 -07:00
u32 ready ;
2011-02-11 13:38:17 +00:00
if ( adapter - > eeh_err ) {
dev_err ( & adapter - > pdev - > dev ,
" Error detected in card.Cannot issue commands \n " ) ;
return - EIO ;
}
2009-03-11 23:32:03 -07:00
do {
2010-02-14 21:22:01 +00:00
ready = ioread32 ( db ) ;
if ( ready = = 0xffffffff ) {
dev_err ( & adapter - > pdev - > dev ,
" pci slot disconnected \n " ) ;
return - 1 ;
}
ready & = MPU_MAILBOX_DB_RDY_MASK ;
2009-03-11 23:32:03 -07:00
if ( ready )
break ;
2010-05-30 23:34:14 +00:00
if ( msecs > 4000 ) {
2009-07-27 22:52:56 +00:00
dev_err ( & adapter - > pdev - > dev , " mbox poll timed out \n " ) ;
2011-05-10 05:13:01 +00:00
if ( ! lancer_chip ( adapter ) )
be_detect_dump_ue ( adapter ) ;
2009-03-11 23:32:03 -07:00
return - 1 ;
}
2011-05-12 19:32:16 +00:00
msleep ( 1 ) ;
2010-05-30 23:34:14 +00:00
msecs + + ;
2009-03-11 23:32:03 -07:00
} while ( true ) ;
return 0 ;
}
/*
* Insert the mailbox address into the doorbell in two steps
2009-06-18 00:02:59 +00:00
* Polls on the mbox doorbell till a command completion ( or a timeout ) occurs
2009-03-11 23:32:03 -07:00
*/
2009-09-17 10:30:13 -07:00
static int be_mbox_notify_wait ( struct be_adapter * adapter )
2009-03-11 23:32:03 -07:00
{
int status ;
u32 val = 0 ;
2009-07-27 22:52:03 +00:00
void __iomem * db = adapter - > db + MPU_MAILBOX_DB_OFFSET ;
struct be_dma_mem * mbox_mem = & adapter - > mbox_mem ;
2009-03-11 23:32:03 -07:00
struct be_mcc_mailbox * mbox = mbox_mem - > va ;
2009-07-27 22:53:10 +00:00
struct be_mcc_compl * compl = & mbox - > compl ;
2009-03-11 23:32:03 -07:00
2010-02-14 21:22:01 +00:00
/* wait for ready to be set */
status = be_mbox_db_ready_wait ( adapter , db ) ;
if ( status ! = 0 )
return status ;
2009-03-11 23:32:03 -07:00
val | = MPU_MAILBOX_DB_HI_MASK ;
/* at bits 2 - 31 place mbox dma addr msb bits 34 - 63 */
val | = ( upper_32_bits ( mbox_mem - > dma ) > > 2 ) < < 2 ;
iowrite32 ( val , db ) ;
/* wait for ready to be set */
2009-07-27 22:52:56 +00:00
status = be_mbox_db_ready_wait ( adapter , db ) ;
2009-03-11 23:32:03 -07:00
if ( status ! = 0 )
return status ;
val = 0 ;
/* at bits 2 - 31 place mbox dma addr lsb bits 4 - 33 */
val | = ( u32 ) ( mbox_mem - > dma > > 4 ) < < 2 ;
iowrite32 ( val , db ) ;
2009-07-27 22:52:56 +00:00
status = be_mbox_db_ready_wait ( adapter , db ) ;
2009-03-11 23:32:03 -07:00
if ( status ! = 0 )
return status ;
2009-06-18 00:02:59 +00:00
/* A cq entry has been made now */
2009-07-27 22:53:10 +00:00
if ( be_mcc_compl_is_new ( compl ) ) {
status = be_mcc_compl_process ( adapter , & mbox - > compl ) ;
be_mcc_compl_use ( compl ) ;
2009-06-18 00:02:59 +00:00
if ( status )
return status ;
} else {
2009-07-27 22:52:56 +00:00
dev_err ( & adapter - > pdev - > dev , " invalid mailbox completion \n " ) ;
2009-03-11 23:32:03 -07:00
return - 1 ;
}
2009-06-18 00:02:59 +00:00
return 0 ;
2009-03-11 23:32:03 -07:00
}
2009-07-27 22:52:03 +00:00
static int be_POST_stage_get ( struct be_adapter * adapter , u16 * stage )
2009-03-11 23:32:03 -07:00
{
2010-11-21 23:25:50 +00:00
u32 sem ;
if ( lancer_chip ( adapter ) )
sem = ioread32 ( adapter - > db + MPU_EP_SEMAPHORE_IF_TYPE2_OFFSET ) ;
else
sem = ioread32 ( adapter - > csr + MPU_EP_SEMAPHORE_OFFSET ) ;
2009-03-11 23:32:03 -07:00
* stage = sem & EP_SEMAPHORE_POST_STAGE_MASK ;
if ( ( sem > > EP_SEMAPHORE_POST_ERR_SHIFT ) & EP_SEMAPHORE_POST_ERR_MASK )
return - 1 ;
else
return 0 ;
}
2009-07-27 22:52:03 +00:00
int be_cmd_POST ( struct be_adapter * adapter )
2009-03-11 23:32:03 -07:00
{
2009-10-14 20:21:17 +00:00
u16 stage ;
int status , timeout = 0 ;
2011-05-12 19:32:15 +00:00
struct device * dev = & adapter - > pdev - > dev ;
2009-03-11 23:32:03 -07:00
2009-10-14 20:21:17 +00:00
do {
status = be_POST_stage_get ( adapter , & stage ) ;
if ( status ) {
2011-05-12 19:32:15 +00:00
dev_err ( dev , " POST error; stage=0x%x \n " , stage ) ;
2009-10-14 20:21:17 +00:00
return - 1 ;
} else if ( stage ! = POST_STAGE_ARMFW_RDY ) {
2011-05-12 19:32:15 +00:00
if ( msleep_interruptible ( 2000 ) ) {
dev_err ( dev , " Waiting for POST aborted \n " ) ;
return - EINTR ;
}
2009-10-14 20:21:17 +00:00
timeout + = 2 ;
} else {
return 0 ;
}
2010-05-26 00:33:43 -07:00
} while ( timeout < 40 ) ;
2009-03-11 23:32:03 -07:00
2011-05-12 19:32:15 +00:00
dev_err ( dev , " POST timeout; stage=0x%x \n " , stage ) ;
2009-10-14 20:21:17 +00:00
return - 1 ;
2009-03-11 23:32:03 -07:00
}
static inline void * embedded_payload ( struct be_mcc_wrb * wrb )
{
return wrb - > payload . embedded_payload ;
}
static inline struct be_sge * nonembedded_sgl ( struct be_mcc_wrb * wrb )
{
return & wrb - > payload . sgl [ 0 ] ;
}
/* Don't touch the hdr after it's prepared */
static void be_wrb_hdr_prepare ( struct be_mcc_wrb * wrb , int payload_len ,
2009-12-03 06:12:06 +00:00
bool embedded , u8 sge_cnt , u32 opcode )
2009-03-11 23:32:03 -07:00
{
if ( embedded )
wrb - > embedded | = MCC_WRB_EMBEDDED_MASK ;
else
wrb - > embedded | = ( sge_cnt & MCC_WRB_SGE_CNT_MASK ) < <
MCC_WRB_SGE_CNT_SHIFT ;
wrb - > payload_length = payload_len ;
2009-12-03 06:12:06 +00:00
wrb - > tag0 = opcode ;
2010-01-21 22:51:36 +00:00
be_dws_cpu_to_le ( wrb , 8 ) ;
2009-03-11 23:32:03 -07:00
}
/* Don't touch the hdr after it's prepared */
static void be_cmd_hdr_prepare ( struct be_cmd_req_hdr * req_hdr ,
u8 subsystem , u8 opcode , int cmd_len )
{
req_hdr - > opcode = opcode ;
req_hdr - > subsystem = subsystem ;
req_hdr - > request_length = cpu_to_le32 ( cmd_len - sizeof ( * req_hdr ) ) ;
2010-02-16 00:18:46 +00:00
req_hdr - > version = 0 ;
2009-03-11 23:32:03 -07:00
}
static void be_cmd_page_addrs_prepare ( struct phys_addr * pages , u32 max_pages ,
struct be_dma_mem * mem )
{
int i , buf_pages = min ( PAGES_4K_SPANNED ( mem - > va , mem - > size ) , max_pages ) ;
u64 dma = ( u64 ) mem - > dma ;
for ( i = 0 ; i < buf_pages ; i + + ) {
pages [ i ] . lo = cpu_to_le32 ( dma & 0xFFFFFFFF ) ;
pages [ i ] . hi = cpu_to_le32 ( upper_32_bits ( dma ) ) ;
dma + = PAGE_SIZE_4K ;
}
}
/* Converts interrupt delay in microseconds to multiplier value */
static u32 eq_delay_to_mult ( u32 usec_delay )
{
# define MAX_INTR_RATE 651042
const u32 round = 10 ;
u32 multiplier ;
if ( usec_delay = = 0 )
multiplier = 0 ;
else {
u32 interrupt_rate = 1000000 / usec_delay ;
/* Max delay, corresponding to the lowest interrupt rate */
if ( interrupt_rate = = 0 )
multiplier = 1023 ;
else {
multiplier = ( MAX_INTR_RATE - interrupt_rate ) * round ;
multiplier / = interrupt_rate ;
/* Round the multiplier to the closest value.*/
multiplier = ( multiplier + round / 2 ) / round ;
multiplier = min ( multiplier , ( u32 ) 1023 ) ;
}
}
return multiplier ;
}
2009-09-17 10:30:13 -07:00
static inline struct be_mcc_wrb * wrb_from_mbox ( struct be_adapter * adapter )
2009-03-11 23:32:03 -07:00
{
2009-09-17 10:30:13 -07:00
struct be_dma_mem * mbox_mem = & adapter - > mbox_mem ;
struct be_mcc_wrb * wrb
= & ( ( struct be_mcc_mailbox * ) ( mbox_mem - > va ) ) - > wrb ;
memset ( wrb , 0 , sizeof ( * wrb ) ) ;
return wrb ;
2009-03-11 23:32:03 -07:00
}
2009-09-17 10:30:13 -07:00
static struct be_mcc_wrb * wrb_from_mccq ( struct be_adapter * adapter )
2009-06-18 00:02:59 +00:00
{
2009-09-17 10:30:13 -07:00
struct be_queue_info * mccq = & adapter - > mcc_obj . q ;
struct be_mcc_wrb * wrb ;
2009-11-22 22:02:45 +00:00
if ( atomic_read ( & mccq - > used ) > = mccq - > len ) {
dev_err ( & adapter - > pdev - > dev , " Out of MCCQ wrbs \n " ) ;
return NULL ;
}
2009-09-17 10:30:13 -07:00
wrb = queue_head_node ( mccq ) ;
queue_head_inc ( mccq ) ;
atomic_inc ( & mccq - > used ) ;
memset ( wrb , 0 , sizeof ( * wrb ) ) ;
2009-06-18 00:02:59 +00:00
return wrb ;
}
2009-11-22 22:02:03 +00:00
/* Tell fw we're about to start firing cmds by writing a
* special pattern across the wrb hdr ; uses mbox
*/
int be_cmd_fw_init ( struct be_adapter * adapter )
{
u8 * wrb ;
int status ;
2010-12-14 05:43:19 +00:00
if ( mutex_lock_interruptible ( & adapter - > mbox_lock ) )
return - 1 ;
2009-11-22 22:02:03 +00:00
wrb = ( u8 * ) wrb_from_mbox ( adapter ) ;
2010-12-01 01:03:36 +00:00
* wrb + + = 0xFF ;
* wrb + + = 0x12 ;
* wrb + + = 0x34 ;
* wrb + + = 0xFF ;
* wrb + + = 0xFF ;
* wrb + + = 0x56 ;
* wrb + + = 0x78 ;
* wrb = 0xFF ;
2009-11-22 22:02:03 +00:00
status = be_mbox_notify_wait ( adapter ) ;
2010-12-14 05:43:19 +00:00
mutex_unlock ( & adapter - > mbox_lock ) ;
2009-11-22 22:02:03 +00:00
return status ;
}
/* Tell fw we're done with firing cmds by writing a
* special pattern across the wrb hdr ; uses mbox
*/
int be_cmd_fw_clean ( struct be_adapter * adapter )
{
u8 * wrb ;
int status ;
2010-02-14 21:22:01 +00:00
if ( adapter - > eeh_err )
return - EIO ;
2010-12-14 05:43:19 +00:00
if ( mutex_lock_interruptible ( & adapter - > mbox_lock ) )
return - 1 ;
2009-11-22 22:02:03 +00:00
wrb = ( u8 * ) wrb_from_mbox ( adapter ) ;
* wrb + + = 0xFF ;
* wrb + + = 0xAA ;
* wrb + + = 0xBB ;
* wrb + + = 0xFF ;
* wrb + + = 0xFF ;
* wrb + + = 0xCC ;
* wrb + + = 0xDD ;
* wrb = 0xFF ;
status = be_mbox_notify_wait ( adapter ) ;
2010-12-14 05:43:19 +00:00
mutex_unlock ( & adapter - > mbox_lock ) ;
2009-11-22 22:02:03 +00:00
return status ;
}
2009-07-27 22:52:03 +00:00
int be_cmd_eq_create ( struct be_adapter * adapter ,
2009-03-11 23:32:03 -07:00
struct be_queue_info * eq , int eq_delay )
{
2009-09-17 10:30:13 -07:00
struct be_mcc_wrb * wrb ;
struct be_cmd_req_eq_create * req ;
2009-03-11 23:32:03 -07:00
struct be_dma_mem * q_mem = & eq - > dma_mem ;
int status ;
2010-12-14 05:43:19 +00:00
if ( mutex_lock_interruptible ( & adapter - > mbox_lock ) )
return - 1 ;
2009-09-17 10:30:13 -07:00
wrb = wrb_from_mbox ( adapter ) ;
req = embedded_payload ( wrb ) ;
2009-03-11 23:32:03 -07:00
2009-12-03 06:12:06 +00:00
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , true , 0 , OPCODE_COMMON_EQ_CREATE ) ;
2009-03-11 23:32:03 -07:00
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_COMMON ,
OPCODE_COMMON_EQ_CREATE , sizeof ( * req ) ) ;
req - > num_pages = cpu_to_le16 ( PAGES_4K_SPANNED ( q_mem - > va , q_mem - > size ) ) ;
AMAP_SET_BITS ( struct amap_eq_context , valid , req - > context , 1 ) ;
/* 4byte eqe*/
AMAP_SET_BITS ( struct amap_eq_context , size , req - > context , 0 ) ;
AMAP_SET_BITS ( struct amap_eq_context , count , req - > context ,
__ilog2_u32 ( eq - > len / 256 ) ) ;
AMAP_SET_BITS ( struct amap_eq_context , delaymult , req - > context ,
eq_delay_to_mult ( eq_delay ) ) ;
be_dws_cpu_to_le ( req - > context , sizeof ( req - > context ) ) ;
be_cmd_page_addrs_prepare ( req - > pages , ARRAY_SIZE ( req - > pages ) , q_mem ) ;
2009-09-17 10:30:13 -07:00
status = be_mbox_notify_wait ( adapter ) ;
2009-03-11 23:32:03 -07:00
if ( ! status ) {
2009-09-17 10:30:13 -07:00
struct be_cmd_resp_eq_create * resp = embedded_payload ( wrb ) ;
2009-03-11 23:32:03 -07:00
eq - > id = le16_to_cpu ( resp - > eq_id ) ;
eq - > created = true ;
}
2009-09-17 10:30:13 -07:00
2010-12-14 05:43:19 +00:00
mutex_unlock ( & adapter - > mbox_lock ) ;
2009-03-11 23:32:03 -07:00
return status ;
}
2009-09-17 10:30:13 -07:00
/* Uses mbox */
2009-07-27 22:52:03 +00:00
int be_cmd_mac_addr_query ( struct be_adapter * adapter , u8 * mac_addr ,
2009-03-11 23:32:03 -07:00
u8 type , bool permanent , u32 if_handle )
{
2009-09-17 10:30:13 -07:00
struct be_mcc_wrb * wrb ;
struct be_cmd_req_mac_query * req ;
2009-03-11 23:32:03 -07:00
int status ;
2010-12-14 05:43:19 +00:00
if ( mutex_lock_interruptible ( & adapter - > mbox_lock ) )
return - 1 ;
2009-09-17 10:30:13 -07:00
wrb = wrb_from_mbox ( adapter ) ;
req = embedded_payload ( wrb ) ;
2009-03-11 23:32:03 -07:00
2009-12-03 06:12:06 +00:00
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , true , 0 ,
OPCODE_COMMON_NTWK_MAC_QUERY ) ;
2009-03-11 23:32:03 -07:00
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_COMMON ,
OPCODE_COMMON_NTWK_MAC_QUERY , sizeof ( * req ) ) ;
req - > type = type ;
if ( permanent ) {
req - > permanent = 1 ;
} else {
2009-09-17 10:30:13 -07:00
req - > if_id = cpu_to_le16 ( ( u16 ) if_handle ) ;
2009-03-11 23:32:03 -07:00
req - > permanent = 0 ;
}
2009-09-17 10:30:13 -07:00
status = be_mbox_notify_wait ( adapter ) ;
if ( ! status ) {
struct be_cmd_resp_mac_query * resp = embedded_payload ( wrb ) ;
2009-03-11 23:32:03 -07:00
memcpy ( mac_addr , resp - > mac . addr , ETH_ALEN ) ;
2009-09-17 10:30:13 -07:00
}
2009-03-11 23:32:03 -07:00
2010-12-14 05:43:19 +00:00
mutex_unlock ( & adapter - > mbox_lock ) ;
2009-03-11 23:32:03 -07:00
return status ;
}
2009-09-17 10:30:13 -07:00
/* Uses synchronous MCCQ */
2009-07-27 22:52:03 +00:00
int be_cmd_pmac_add ( struct be_adapter * adapter , u8 * mac_addr ,
2011-02-11 13:36:37 +00:00
u32 if_id , u32 * pmac_id , u32 domain )
2009-03-11 23:32:03 -07:00
{
2009-09-17 10:30:13 -07:00
struct be_mcc_wrb * wrb ;
struct be_cmd_req_pmac_add * req ;
2009-03-11 23:32:03 -07:00
int status ;
2009-09-17 10:30:13 -07:00
spin_lock_bh ( & adapter - > mcc_lock ) ;
wrb = wrb_from_mccq ( adapter ) ;
2009-11-22 22:02:45 +00:00
if ( ! wrb ) {
status = - EBUSY ;
goto err ;
}
2009-09-17 10:30:13 -07:00
req = embedded_payload ( wrb ) ;
2009-03-11 23:32:03 -07:00
2009-12-03 06:12:06 +00:00
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , true , 0 ,
OPCODE_COMMON_NTWK_PMAC_ADD ) ;
2009-03-11 23:32:03 -07:00
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_COMMON ,
OPCODE_COMMON_NTWK_PMAC_ADD , sizeof ( * req ) ) ;
2011-02-11 13:36:37 +00:00
req - > hdr . domain = domain ;
2009-03-11 23:32:03 -07:00
req - > if_id = cpu_to_le32 ( if_id ) ;
memcpy ( req - > mac_address , mac_addr , ETH_ALEN ) ;
2009-09-17 10:30:13 -07:00
status = be_mcc_notify_wait ( adapter ) ;
2009-03-11 23:32:03 -07:00
if ( ! status ) {
struct be_cmd_resp_pmac_add * resp = embedded_payload ( wrb ) ;
* pmac_id = le32_to_cpu ( resp - > pmac_id ) ;
}
2009-11-22 22:02:45 +00:00
err :
2009-09-17 10:30:13 -07:00
spin_unlock_bh ( & adapter - > mcc_lock ) ;
2009-03-11 23:32:03 -07:00
return status ;
}
2009-09-17 10:30:13 -07:00
/* Uses synchronous MCCQ */
2011-02-11 13:36:37 +00:00
int be_cmd_pmac_del ( struct be_adapter * adapter , u32 if_id , u32 pmac_id , u32 dom )
2009-03-11 23:32:03 -07:00
{
2009-09-17 10:30:13 -07:00
struct be_mcc_wrb * wrb ;
struct be_cmd_req_pmac_del * req ;
2009-03-11 23:32:03 -07:00
int status ;
2009-09-17 10:30:13 -07:00
spin_lock_bh ( & adapter - > mcc_lock ) ;
wrb = wrb_from_mccq ( adapter ) ;
2009-11-22 22:02:45 +00:00
if ( ! wrb ) {
status = - EBUSY ;
goto err ;
}
2009-09-17 10:30:13 -07:00
req = embedded_payload ( wrb ) ;
2009-03-11 23:32:03 -07:00
2009-12-03 06:12:06 +00:00
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , true , 0 ,
OPCODE_COMMON_NTWK_PMAC_DEL ) ;
2009-03-11 23:32:03 -07:00
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_COMMON ,
OPCODE_COMMON_NTWK_PMAC_DEL , sizeof ( * req ) ) ;
2011-02-11 13:36:37 +00:00
req - > hdr . domain = dom ;
2009-03-11 23:32:03 -07:00
req - > if_id = cpu_to_le32 ( if_id ) ;
req - > pmac_id = cpu_to_le32 ( pmac_id ) ;
2009-09-17 10:30:13 -07:00
status = be_mcc_notify_wait ( adapter ) ;
2009-11-22 22:02:45 +00:00
err :
2009-09-17 10:30:13 -07:00
spin_unlock_bh ( & adapter - > mcc_lock ) ;
2009-03-11 23:32:03 -07:00
return status ;
}
2009-09-17 10:30:13 -07:00
/* Uses Mbox */
2009-07-27 22:52:03 +00:00
int be_cmd_cq_create ( struct be_adapter * adapter ,
2009-03-11 23:32:03 -07:00
struct be_queue_info * cq , struct be_queue_info * eq ,
bool sol_evts , bool no_delay , int coalesce_wm )
{
2009-09-17 10:30:13 -07:00
struct be_mcc_wrb * wrb ;
struct be_cmd_req_cq_create * req ;
2009-03-11 23:32:03 -07:00
struct be_dma_mem * q_mem = & cq - > dma_mem ;
2009-09-17 10:30:13 -07:00
void * ctxt ;
2009-03-11 23:32:03 -07:00
int status ;
2010-12-14 05:43:19 +00:00
if ( mutex_lock_interruptible ( & adapter - > mbox_lock ) )
return - 1 ;
2009-09-17 10:30:13 -07:00
wrb = wrb_from_mbox ( adapter ) ;
req = embedded_payload ( wrb ) ;
ctxt = & req - > context ;
2009-03-11 23:32:03 -07:00
2009-12-03 06:12:06 +00:00
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , true , 0 ,
OPCODE_COMMON_CQ_CREATE ) ;
2009-03-11 23:32:03 -07:00
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_COMMON ,
OPCODE_COMMON_CQ_CREATE , sizeof ( * req ) ) ;
req - > num_pages = cpu_to_le16 ( PAGES_4K_SPANNED ( q_mem - > va , q_mem - > size ) ) ;
2010-11-21 23:25:50 +00:00
if ( lancer_chip ( adapter ) ) {
2011-03-07 03:08:52 +00:00
req - > hdr . version = 2 ;
2010-11-21 23:25:50 +00:00
req - > page_size = 1 ; /* 1 for 4K */
AMAP_SET_BITS ( struct amap_cq_context_lancer , nodelay , ctxt ,
no_delay ) ;
AMAP_SET_BITS ( struct amap_cq_context_lancer , count , ctxt ,
__ilog2_u32 ( cq - > len / 256 ) ) ;
AMAP_SET_BITS ( struct amap_cq_context_lancer , valid , ctxt , 1 ) ;
AMAP_SET_BITS ( struct amap_cq_context_lancer , eventable ,
ctxt , 1 ) ;
AMAP_SET_BITS ( struct amap_cq_context_lancer , eqid ,
ctxt , eq - > id ) ;
AMAP_SET_BITS ( struct amap_cq_context_lancer , armed , ctxt , 1 ) ;
} else {
AMAP_SET_BITS ( struct amap_cq_context_be , coalescwm , ctxt ,
coalesce_wm ) ;
AMAP_SET_BITS ( struct amap_cq_context_be , nodelay ,
ctxt , no_delay ) ;
AMAP_SET_BITS ( struct amap_cq_context_be , count , ctxt ,
__ilog2_u32 ( cq - > len / 256 ) ) ;
AMAP_SET_BITS ( struct amap_cq_context_be , valid , ctxt , 1 ) ;
AMAP_SET_BITS ( struct amap_cq_context_be , solevent ,
ctxt , sol_evts ) ;
AMAP_SET_BITS ( struct amap_cq_context_be , eventable , ctxt , 1 ) ;
AMAP_SET_BITS ( struct amap_cq_context_be , eqid , ctxt , eq - > id ) ;
AMAP_SET_BITS ( struct amap_cq_context_be , armed , ctxt , 1 ) ;
}
2009-03-11 23:32:03 -07:00
be_dws_cpu_to_le ( ctxt , sizeof ( req - > context ) ) ;
be_cmd_page_addrs_prepare ( req - > pages , ARRAY_SIZE ( req - > pages ) , q_mem ) ;
2009-09-17 10:30:13 -07:00
status = be_mbox_notify_wait ( adapter ) ;
2009-03-11 23:32:03 -07:00
if ( ! status ) {
2009-09-17 10:30:13 -07:00
struct be_cmd_resp_cq_create * resp = embedded_payload ( wrb ) ;
2009-03-11 23:32:03 -07:00
cq - > id = le16_to_cpu ( resp - > cq_id ) ;
cq - > created = true ;
}
2009-09-17 10:30:13 -07:00
2010-12-14 05:43:19 +00:00
mutex_unlock ( & adapter - > mbox_lock ) ;
2009-06-18 00:02:59 +00:00
return status ;
}
static u32 be_encoded_q_len ( int q_len )
{
u32 len_encoded = fls ( q_len ) ; /* log2(len) + 1 */
if ( len_encoded = = 16 )
len_encoded = 0 ;
return len_encoded ;
}
2011-06-01 00:33:22 +00:00
int be_cmd_mccq_ext_create ( struct be_adapter * adapter ,
2009-06-18 00:02:59 +00:00
struct be_queue_info * mccq ,
struct be_queue_info * cq )
{
2009-09-17 10:30:13 -07:00
struct be_mcc_wrb * wrb ;
2011-06-01 00:33:22 +00:00
struct be_cmd_req_mcc_ext_create * req ;
2009-06-18 00:02:59 +00:00
struct be_dma_mem * q_mem = & mccq - > dma_mem ;
2009-09-17 10:30:13 -07:00
void * ctxt ;
2009-06-18 00:02:59 +00:00
int status ;
2010-12-14 05:43:19 +00:00
if ( mutex_lock_interruptible ( & adapter - > mbox_lock ) )
return - 1 ;
2009-09-17 10:30:13 -07:00
wrb = wrb_from_mbox ( adapter ) ;
req = embedded_payload ( wrb ) ;
ctxt = & req - > context ;
2009-06-18 00:02:59 +00:00
2009-12-03 06:12:06 +00:00
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , true , 0 ,
2010-10-21 07:11:14 -07:00
OPCODE_COMMON_MCC_CREATE_EXT ) ;
2009-06-18 00:02:59 +00:00
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_COMMON ,
2010-10-21 07:11:14 -07:00
OPCODE_COMMON_MCC_CREATE_EXT , sizeof ( * req ) ) ;
2009-06-18 00:02:59 +00:00
2010-03-11 01:35:59 +00:00
req - > num_pages = cpu_to_le16 ( PAGES_4K_SPANNED ( q_mem - > va , q_mem - > size ) ) ;
2010-11-21 23:25:50 +00:00
if ( lancer_chip ( adapter ) ) {
req - > hdr . version = 1 ;
req - > cq_id = cpu_to_le16 ( cq - > id ) ;
AMAP_SET_BITS ( struct amap_mcc_context_lancer , ring_size , ctxt ,
be_encoded_q_len ( mccq - > len ) ) ;
AMAP_SET_BITS ( struct amap_mcc_context_lancer , valid , ctxt , 1 ) ;
AMAP_SET_BITS ( struct amap_mcc_context_lancer , async_cq_id ,
ctxt , cq - > id ) ;
AMAP_SET_BITS ( struct amap_mcc_context_lancer , async_cq_valid ,
ctxt , 1 ) ;
} else {
AMAP_SET_BITS ( struct amap_mcc_context_be , valid , ctxt , 1 ) ;
AMAP_SET_BITS ( struct amap_mcc_context_be , ring_size , ctxt ,
be_encoded_q_len ( mccq - > len ) ) ;
AMAP_SET_BITS ( struct amap_mcc_context_be , cq_id , ctxt , cq - > id ) ;
}
2009-06-18 00:02:59 +00:00
2010-10-21 07:11:14 -07:00
/* Subscribe to Link State and Group 5 Events(bits 1 and 5 set) */
2010-11-21 23:25:50 +00:00
req - > async_event_bitmap [ 0 ] = cpu_to_le32 ( 0x00000022 ) ;
2009-06-18 00:02:59 +00:00
be_dws_cpu_to_le ( ctxt , sizeof ( req - > context ) ) ;
be_cmd_page_addrs_prepare ( req - > pages , ARRAY_SIZE ( req - > pages ) , q_mem ) ;
2009-09-17 10:30:13 -07:00
status = be_mbox_notify_wait ( adapter ) ;
2009-06-18 00:02:59 +00:00
if ( ! status ) {
struct be_cmd_resp_mcc_create * resp = embedded_payload ( wrb ) ;
mccq - > id = le16_to_cpu ( resp - > id ) ;
mccq - > created = true ;
}
2010-12-14 05:43:19 +00:00
mutex_unlock ( & adapter - > mbox_lock ) ;
2009-03-11 23:32:03 -07:00
return status ;
}
2011-06-01 00:33:22 +00:00
int be_cmd_mccq_org_create ( struct be_adapter * adapter ,
struct be_queue_info * mccq ,
struct be_queue_info * cq )
{
struct be_mcc_wrb * wrb ;
struct be_cmd_req_mcc_create * req ;
struct be_dma_mem * q_mem = & mccq - > dma_mem ;
void * ctxt ;
int status ;
if ( mutex_lock_interruptible ( & adapter - > mbox_lock ) )
return - 1 ;
wrb = wrb_from_mbox ( adapter ) ;
req = embedded_payload ( wrb ) ;
ctxt = & req - > context ;
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , true , 0 ,
OPCODE_COMMON_MCC_CREATE ) ;
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_COMMON ,
OPCODE_COMMON_MCC_CREATE , sizeof ( * req ) ) ;
req - > num_pages = cpu_to_le16 ( PAGES_4K_SPANNED ( q_mem - > va , q_mem - > size ) ) ;
AMAP_SET_BITS ( struct amap_mcc_context_be , valid , ctxt , 1 ) ;
AMAP_SET_BITS ( struct amap_mcc_context_be , ring_size , ctxt ,
be_encoded_q_len ( mccq - > len ) ) ;
AMAP_SET_BITS ( struct amap_mcc_context_be , cq_id , ctxt , cq - > id ) ;
be_dws_cpu_to_le ( ctxt , sizeof ( req - > context ) ) ;
be_cmd_page_addrs_prepare ( req - > pages , ARRAY_SIZE ( req - > pages ) , q_mem ) ;
status = be_mbox_notify_wait ( adapter ) ;
if ( ! status ) {
struct be_cmd_resp_mcc_create * resp = embedded_payload ( wrb ) ;
mccq - > id = le16_to_cpu ( resp - > id ) ;
mccq - > created = true ;
}
mutex_unlock ( & adapter - > mbox_lock ) ;
return status ;
}
int be_cmd_mccq_create ( struct be_adapter * adapter ,
struct be_queue_info * mccq ,
struct be_queue_info * cq )
{
int status ;
status = be_cmd_mccq_ext_create ( adapter , mccq , cq ) ;
if ( status & & ! lancer_chip ( adapter ) ) {
dev_warn ( & adapter - > pdev - > dev , " Upgrade to F/W ver 2.102.235.0 "
" or newer to avoid conflicting priorities between NIC "
" and FCoE traffic " ) ;
status = be_cmd_mccq_org_create ( adapter , mccq , cq ) ;
}
return status ;
}
2009-07-27 22:52:03 +00:00
int be_cmd_txq_create ( struct be_adapter * adapter ,
2009-03-11 23:32:03 -07:00
struct be_queue_info * txq ,
struct be_queue_info * cq )
{
2009-09-17 10:30:13 -07:00
struct be_mcc_wrb * wrb ;
struct be_cmd_req_eth_tx_create * req ;
2009-03-11 23:32:03 -07:00
struct be_dma_mem * q_mem = & txq - > dma_mem ;
2009-09-17 10:30:13 -07:00
void * ctxt ;
2009-03-11 23:32:03 -07:00
int status ;
2010-12-14 05:43:19 +00:00
if ( mutex_lock_interruptible ( & adapter - > mbox_lock ) )
return - 1 ;
2009-09-17 10:30:13 -07:00
wrb = wrb_from_mbox ( adapter ) ;
req = embedded_payload ( wrb ) ;
ctxt = & req - > context ;
2009-03-11 23:32:03 -07:00
2009-12-03 06:12:06 +00:00
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , true , 0 ,
OPCODE_ETH_TX_CREATE ) ;
2009-03-11 23:32:03 -07:00
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_ETH , OPCODE_ETH_TX_CREATE ,
sizeof ( * req ) ) ;
2011-03-07 03:08:52 +00:00
if ( lancer_chip ( adapter ) ) {
req - > hdr . version = 1 ;
AMAP_SET_BITS ( struct amap_tx_context , if_id , ctxt ,
adapter - > if_handle ) ;
}
2009-03-11 23:32:03 -07:00
req - > num_pages = PAGES_4K_SPANNED ( q_mem - > va , q_mem - > size ) ;
req - > ulp_num = BE_ULP1_NUM ;
req - > type = BE_ETH_TX_RING_TYPE_STANDARD ;
2009-09-17 10:30:13 -07:00
AMAP_SET_BITS ( struct amap_tx_context , tx_ring_size , ctxt ,
be_encoded_q_len ( txq - > len ) ) ;
2009-03-11 23:32:03 -07:00
AMAP_SET_BITS ( struct amap_tx_context , ctx_valid , ctxt , 1 ) ;
AMAP_SET_BITS ( struct amap_tx_context , cq_id_send , ctxt , cq - > id ) ;
be_dws_cpu_to_le ( ctxt , sizeof ( req - > context ) ) ;
be_cmd_page_addrs_prepare ( req - > pages , ARRAY_SIZE ( req - > pages ) , q_mem ) ;
2009-09-17 10:30:13 -07:00
status = be_mbox_notify_wait ( adapter ) ;
2009-03-11 23:32:03 -07:00
if ( ! status ) {
struct be_cmd_resp_eth_tx_create * resp = embedded_payload ( wrb ) ;
txq - > id = le16_to_cpu ( resp - > cid ) ;
txq - > created = true ;
}
2009-09-17 10:30:13 -07:00
2010-12-14 05:43:19 +00:00
mutex_unlock ( & adapter - > mbox_lock ) ;
2009-03-11 23:32:03 -07:00
return status ;
}
2011-06-29 23:33:17 +00:00
/* Uses MCC */
2009-07-27 22:52:03 +00:00
int be_cmd_rxq_create ( struct be_adapter * adapter ,
2009-03-11 23:32:03 -07:00
struct be_queue_info * rxq , u16 cq_id , u16 frag_size ,
2010-10-03 22:12:27 -07:00
u16 max_frame_size , u32 if_id , u32 rss , u8 * rss_id )
2009-03-11 23:32:03 -07:00
{
2009-09-17 10:30:13 -07:00
struct be_mcc_wrb * wrb ;
struct be_cmd_req_eth_rx_create * req ;
2009-03-11 23:32:03 -07:00
struct be_dma_mem * q_mem = & rxq - > dma_mem ;
int status ;
2011-06-29 23:33:17 +00:00
spin_lock_bh ( & adapter - > mcc_lock ) ;
2009-09-17 10:30:13 -07:00
2011-06-29 23:33:17 +00:00
wrb = wrb_from_mccq ( adapter ) ;
if ( ! wrb ) {
status = - EBUSY ;
goto err ;
}
2009-09-17 10:30:13 -07:00
req = embedded_payload ( wrb ) ;
2009-03-11 23:32:03 -07:00
2009-12-03 06:12:06 +00:00
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , true , 0 ,
OPCODE_ETH_RX_CREATE ) ;
2009-03-11 23:32:03 -07:00
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_ETH , OPCODE_ETH_RX_CREATE ,
sizeof ( * req ) ) ;
req - > cq_id = cpu_to_le16 ( cq_id ) ;
req - > frag_size = fls ( frag_size ) - 1 ;
req - > num_pages = 2 ;
be_cmd_page_addrs_prepare ( req - > pages , ARRAY_SIZE ( req - > pages ) , q_mem ) ;
req - > interface_id = cpu_to_le32 ( if_id ) ;
req - > max_frame_size = cpu_to_le16 ( max_frame_size ) ;
req - > rss_queue = cpu_to_le32 ( rss ) ;
2011-06-29 23:33:17 +00:00
status = be_mcc_notify_wait ( adapter ) ;
2009-03-11 23:32:03 -07:00
if ( ! status ) {
struct be_cmd_resp_eth_rx_create * resp = embedded_payload ( wrb ) ;
rxq - > id = le16_to_cpu ( resp - > id ) ;
rxq - > created = true ;
2010-10-03 22:12:27 -07:00
* rss_id = resp - > rss_id ;
2009-03-11 23:32:03 -07:00
}
2009-09-17 10:30:13 -07:00
2011-06-29 23:33:17 +00:00
err :
spin_unlock_bh ( & adapter - > mcc_lock ) ;
2009-03-11 23:32:03 -07:00
return status ;
}
2009-09-17 10:30:13 -07:00
/* Generic destroyer function for all types of queues
* Uses Mbox
*/
2009-07-27 22:52:03 +00:00
int be_cmd_q_destroy ( struct be_adapter * adapter , struct be_queue_info * q ,
2009-03-11 23:32:03 -07:00
int queue_type )
{
2009-09-17 10:30:13 -07:00
struct be_mcc_wrb * wrb ;
struct be_cmd_req_q_destroy * req ;
2009-03-11 23:32:03 -07:00
u8 subsys = 0 , opcode = 0 ;
int status ;
2010-02-14 21:22:01 +00:00
if ( adapter - > eeh_err )
return - EIO ;
2010-12-14 05:43:19 +00:00
if ( mutex_lock_interruptible ( & adapter - > mbox_lock ) )
return - 1 ;
2009-03-11 23:32:03 -07:00
2009-09-17 10:30:13 -07:00
wrb = wrb_from_mbox ( adapter ) ;
req = embedded_payload ( wrb ) ;
2009-03-11 23:32:03 -07:00
switch ( queue_type ) {
case QTYPE_EQ :
subsys = CMD_SUBSYSTEM_COMMON ;
opcode = OPCODE_COMMON_EQ_DESTROY ;
break ;
case QTYPE_CQ :
subsys = CMD_SUBSYSTEM_COMMON ;
opcode = OPCODE_COMMON_CQ_DESTROY ;
break ;
case QTYPE_TXQ :
subsys = CMD_SUBSYSTEM_ETH ;
opcode = OPCODE_ETH_TX_DESTROY ;
break ;
case QTYPE_RXQ :
subsys = CMD_SUBSYSTEM_ETH ;
opcode = OPCODE_ETH_RX_DESTROY ;
break ;
2009-06-18 00:02:59 +00:00
case QTYPE_MCCQ :
subsys = CMD_SUBSYSTEM_COMMON ;
opcode = OPCODE_COMMON_MCC_DESTROY ;
break ;
2009-03-11 23:32:03 -07:00
default :
2009-07-27 22:52:56 +00:00
BUG ( ) ;
2009-03-11 23:32:03 -07:00
}
2009-12-03 06:12:06 +00:00
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , true , 0 , opcode ) ;
2009-03-11 23:32:03 -07:00
be_cmd_hdr_prepare ( & req - > hdr , subsys , opcode , sizeof ( * req ) ) ;
req - > id = cpu_to_le16 ( q - > id ) ;
2009-09-17 10:30:13 -07:00
status = be_mbox_notify_wait ( adapter ) ;
2011-06-29 23:33:17 +00:00
if ( ! status )
q - > created = false ;
2009-07-27 22:52:56 +00:00
2010-12-14 05:43:19 +00:00
mutex_unlock ( & adapter - > mbox_lock ) ;
2011-06-29 23:33:17 +00:00
return status ;
}
2009-03-11 23:32:03 -07:00
2011-06-29 23:33:17 +00:00
/* Uses MCC */
int be_cmd_rxq_destroy ( struct be_adapter * adapter , struct be_queue_info * q )
{
struct be_mcc_wrb * wrb ;
struct be_cmd_req_q_destroy * req ;
int status ;
spin_lock_bh ( & adapter - > mcc_lock ) ;
wrb = wrb_from_mccq ( adapter ) ;
if ( ! wrb ) {
status = - EBUSY ;
goto err ;
}
req = embedded_payload ( wrb ) ;
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , true , 0 , OPCODE_ETH_RX_DESTROY ) ;
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_ETH , OPCODE_ETH_RX_DESTROY ,
sizeof ( * req ) ) ;
req - > id = cpu_to_le16 ( q - > id ) ;
status = be_mcc_notify_wait ( adapter ) ;
if ( ! status )
q - > created = false ;
err :
spin_unlock_bh ( & adapter - > mcc_lock ) ;
2009-03-11 23:32:03 -07:00
return status ;
}
2009-09-17 10:30:13 -07:00
/* Create an rx filtering policy configuration on an i/f
* Uses mbox
*/
2009-10-14 20:20:42 +00:00
int be_cmd_if_create ( struct be_adapter * adapter , u32 cap_flags , u32 en_flags ,
2010-03-31 02:56:12 +00:00
u8 * mac , bool pmac_invalid , u32 * if_handle , u32 * pmac_id ,
u32 domain )
2009-03-11 23:32:03 -07:00
{
2009-09-17 10:30:13 -07:00
struct be_mcc_wrb * wrb ;
struct be_cmd_req_if_create * req ;
2009-03-11 23:32:03 -07:00
int status ;
2010-12-14 05:43:19 +00:00
if ( mutex_lock_interruptible ( & adapter - > mbox_lock ) )
return - 1 ;
2009-09-17 10:30:13 -07:00
wrb = wrb_from_mbox ( adapter ) ;
req = embedded_payload ( wrb ) ;
2009-03-11 23:32:03 -07:00
2009-12-03 06:12:06 +00:00
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , true , 0 ,
OPCODE_COMMON_NTWK_INTERFACE_CREATE ) ;
2009-03-11 23:32:03 -07:00
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_COMMON ,
OPCODE_COMMON_NTWK_INTERFACE_CREATE , sizeof ( * req ) ) ;
2010-03-31 02:56:12 +00:00
req - > hdr . domain = domain ;
2009-10-14 20:20:42 +00:00
req - > capability_flags = cpu_to_le32 ( cap_flags ) ;
req - > enable_flags = cpu_to_le32 ( en_flags ) ;
2009-09-17 10:30:13 -07:00
req - > pmac_invalid = pmac_invalid ;
2009-03-11 23:32:03 -07:00
if ( ! pmac_invalid )
memcpy ( req - > mac_addr , mac , ETH_ALEN ) ;
2009-09-17 10:30:13 -07:00
status = be_mbox_notify_wait ( adapter ) ;
2009-03-11 23:32:03 -07:00
if ( ! status ) {
struct be_cmd_resp_if_create * resp = embedded_payload ( wrb ) ;
* if_handle = le32_to_cpu ( resp - > interface_id ) ;
if ( ! pmac_invalid )
* pmac_id = le32_to_cpu ( resp - > pmac_id ) ;
}
2010-12-14 05:43:19 +00:00
mutex_unlock ( & adapter - > mbox_lock ) ;
2009-03-11 23:32:03 -07:00
return status ;
}
2009-09-17 10:30:13 -07:00
/* Uses mbox */
2011-02-11 13:34:46 +00:00
int be_cmd_if_destroy ( struct be_adapter * adapter , u32 interface_id , u32 domain )
2009-03-11 23:32:03 -07:00
{
2009-09-17 10:30:13 -07:00
struct be_mcc_wrb * wrb ;
struct be_cmd_req_if_destroy * req ;
2009-03-11 23:32:03 -07:00
int status ;
2010-02-14 21:22:01 +00:00
if ( adapter - > eeh_err )
return - EIO ;
2010-12-14 05:43:19 +00:00
if ( mutex_lock_interruptible ( & adapter - > mbox_lock ) )
return - 1 ;
2009-09-17 10:30:13 -07:00
wrb = wrb_from_mbox ( adapter ) ;
req = embedded_payload ( wrb ) ;
2009-03-11 23:32:03 -07:00
2009-12-03 06:12:06 +00:00
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , true , 0 ,
OPCODE_COMMON_NTWK_INTERFACE_DESTROY ) ;
2009-03-11 23:32:03 -07:00
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_COMMON ,
OPCODE_COMMON_NTWK_INTERFACE_DESTROY , sizeof ( * req ) ) ;
2011-02-11 13:34:46 +00:00
req - > hdr . domain = domain ;
2009-03-11 23:32:03 -07:00
req - > interface_id = cpu_to_le32 ( interface_id ) ;
2009-09-17 10:30:13 -07:00
status = be_mbox_notify_wait ( adapter ) ;
2009-03-11 23:32:03 -07:00
2010-12-14 05:43:19 +00:00
mutex_unlock ( & adapter - > mbox_lock ) ;
2009-03-11 23:32:03 -07:00
return status ;
}
/* Get stats is a non embedded command: the request is not embedded inside
* WRB but is a separate dma memory block
2009-09-17 10:30:13 -07:00
* Uses asynchronous MCC
2009-03-11 23:32:03 -07:00
*/
2009-07-27 22:52:03 +00:00
int be_cmd_get_stats ( struct be_adapter * adapter , struct be_dma_mem * nonemb_cmd )
2009-03-11 23:32:03 -07:00
{
2009-09-17 10:30:13 -07:00
struct be_mcc_wrb * wrb ;
2011-05-16 07:36:18 +00:00
struct be_cmd_req_hdr * hdr ;
2009-09-17 10:30:13 -07:00
struct be_sge * sge ;
2009-11-22 22:02:45 +00:00
int status = 0 ;
2009-03-11 23:32:03 -07:00
2011-02-20 11:42:07 +00:00
if ( MODULO ( adapter - > work_counter , be_get_temp_freq ) = = 0 )
be_cmd_get_die_temperature ( adapter ) ;
2009-09-17 10:30:13 -07:00
spin_lock_bh ( & adapter - > mcc_lock ) ;
2009-03-11 23:32:03 -07:00
2009-09-17 10:30:13 -07:00
wrb = wrb_from_mccq ( adapter ) ;
2009-11-22 22:02:45 +00:00
if ( ! wrb ) {
status = - EBUSY ;
goto err ;
}
2011-05-16 07:36:18 +00:00
hdr = nonemb_cmd - > va ;
2009-09-17 10:30:13 -07:00
sge = nonembedded_sgl ( wrb ) ;
2009-03-11 23:32:03 -07:00
2011-05-16 07:36:18 +00:00
be_wrb_hdr_prepare ( wrb , nonemb_cmd - > size , false , 1 ,
2009-12-03 06:12:06 +00:00
OPCODE_ETH_GET_STATISTICS ) ;
2009-03-11 23:32:03 -07:00
2011-05-16 07:36:18 +00:00
be_cmd_hdr_prepare ( hdr , CMD_SUBSYSTEM_ETH ,
OPCODE_ETH_GET_STATISTICS , nonemb_cmd - > size ) ;
if ( adapter - > generation = = BE_GEN3 )
hdr - > version = 1 ;
2011-04-19 12:11:02 +00:00
wrb - > tag1 = CMD_SUBSYSTEM_ETH ;
2009-03-11 23:32:03 -07:00
sge - > pa_hi = cpu_to_le32 ( upper_32_bits ( nonemb_cmd - > dma ) ) ;
sge - > pa_lo = cpu_to_le32 ( nonemb_cmd - > dma & 0xFFFFFFFF ) ;
sge - > len = cpu_to_le32 ( nonemb_cmd - > size ) ;
2009-09-17 10:30:13 -07:00
be_mcc_notify ( adapter ) ;
2011-02-20 11:41:39 +00:00
adapter - > stats_cmd_sent = true ;
2009-03-11 23:32:03 -07:00
2009-11-22 22:02:45 +00:00
err :
2009-09-17 10:30:13 -07:00
spin_unlock_bh ( & adapter - > mcc_lock ) ;
2009-11-22 22:02:45 +00:00
return status ;
2009-03-11 23:32:03 -07:00
}
2011-05-16 07:36:35 +00:00
/* Lancer Stats */
int lancer_cmd_get_pport_stats ( struct be_adapter * adapter ,
struct be_dma_mem * nonemb_cmd )
{
struct be_mcc_wrb * wrb ;
struct lancer_cmd_req_pport_stats * req ;
struct be_sge * sge ;
int status = 0 ;
spin_lock_bh ( & adapter - > mcc_lock ) ;
wrb = wrb_from_mccq ( adapter ) ;
if ( ! wrb ) {
status = - EBUSY ;
goto err ;
}
req = nonemb_cmd - > va ;
sge = nonembedded_sgl ( wrb ) ;
be_wrb_hdr_prepare ( wrb , nonemb_cmd - > size , false , 1 ,
OPCODE_ETH_GET_PPORT_STATS ) ;
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_ETH ,
OPCODE_ETH_GET_PPORT_STATS , nonemb_cmd - > size ) ;
req - > cmd_params . params . pport_num = cpu_to_le16 ( adapter - > port_num ) ;
req - > cmd_params . params . reset_stats = 0 ;
wrb - > tag1 = CMD_SUBSYSTEM_ETH ;
sge - > pa_hi = cpu_to_le32 ( upper_32_bits ( nonemb_cmd - > dma ) ) ;
sge - > pa_lo = cpu_to_le32 ( nonemb_cmd - > dma & 0xFFFFFFFF ) ;
sge - > len = cpu_to_le32 ( nonemb_cmd - > size ) ;
be_mcc_notify ( adapter ) ;
adapter - > stats_cmd_sent = true ;
err :
spin_unlock_bh ( & adapter - > mcc_lock ) ;
return status ;
}
2009-09-17 10:30:13 -07:00
/* Uses synchronous mcc */
2009-07-27 22:52:03 +00:00
int be_cmd_link_status_query ( struct be_adapter * adapter ,
2011-04-19 12:11:46 +00:00
bool * link_up , u8 * mac_speed , u16 * link_speed , u32 dom )
2009-03-11 23:32:03 -07:00
{
2009-09-17 10:30:13 -07:00
struct be_mcc_wrb * wrb ;
struct be_cmd_req_link_status * req ;
2009-03-11 23:32:03 -07:00
int status ;
2009-09-17 10:30:13 -07:00
spin_lock_bh ( & adapter - > mcc_lock ) ;
wrb = wrb_from_mccq ( adapter ) ;
2009-11-22 22:02:45 +00:00
if ( ! wrb ) {
status = - EBUSY ;
goto err ;
}
2009-09-17 10:30:13 -07:00
req = embedded_payload ( wrb ) ;
2009-06-18 00:10:27 +00:00
* link_up = false ;
2009-03-11 23:32:03 -07:00
2009-12-03 06:12:06 +00:00
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , true , 0 ,
OPCODE_COMMON_NTWK_LINK_STATUS_QUERY ) ;
2009-03-11 23:32:03 -07:00
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_COMMON ,
OPCODE_COMMON_NTWK_LINK_STATUS_QUERY , sizeof ( * req ) ) ;
2009-09-17 10:30:13 -07:00
status = be_mcc_notify_wait ( adapter ) ;
2009-03-11 23:32:03 -07:00
if ( ! status ) {
struct be_cmd_resp_link_status * resp = embedded_payload ( wrb ) ;
2009-10-28 04:15:20 -07:00
if ( resp - > mac_speed ! = PHY_LINK_SPEED_ZERO ) {
2009-06-18 00:10:27 +00:00
* link_up = true ;
2009-10-28 04:15:20 -07:00
* link_speed = le16_to_cpu ( resp - > link_speed ) ;
* mac_speed = resp - > mac_speed ;
}
2009-03-11 23:32:03 -07:00
}
2009-11-22 22:02:45 +00:00
err :
2009-09-17 10:30:13 -07:00
spin_unlock_bh ( & adapter - > mcc_lock ) ;
2009-03-11 23:32:03 -07:00
return status ;
}
2011-02-20 11:42:07 +00:00
/* Uses synchronous mcc */
int be_cmd_get_die_temperature ( struct be_adapter * adapter )
{
struct be_mcc_wrb * wrb ;
struct be_cmd_req_get_cntl_addnl_attribs * req ;
int status ;
spin_lock_bh ( & adapter - > mcc_lock ) ;
wrb = wrb_from_mccq ( adapter ) ;
if ( ! wrb ) {
status = - EBUSY ;
goto err ;
}
req = embedded_payload ( wrb ) ;
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , true , 0 ,
OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES ) ;
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_COMMON ,
OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES , sizeof ( * req ) ) ;
status = be_mcc_notify_wait ( adapter ) ;
if ( ! status ) {
struct be_cmd_resp_get_cntl_addnl_attribs * resp =
embedded_payload ( wrb ) ;
adapter - > drv_stats . be_on_die_temperature =
resp - > on_die_temperature ;
}
/* If IOCTL fails once, do not bother issuing it again */
else
be_get_temp_freq = 0 ;
err :
spin_unlock_bh ( & adapter - > mcc_lock ) ;
return status ;
}
2011-03-16 21:22:43 +00:00
/* Uses synchronous mcc */
int be_cmd_get_reg_len ( struct be_adapter * adapter , u32 * log_size )
{
struct be_mcc_wrb * wrb ;
struct be_cmd_req_get_fat * req ;
int status ;
spin_lock_bh ( & adapter - > mcc_lock ) ;
wrb = wrb_from_mccq ( adapter ) ;
if ( ! wrb ) {
status = - EBUSY ;
goto err ;
}
req = embedded_payload ( wrb ) ;
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , true , 0 ,
OPCODE_COMMON_MANAGE_FAT ) ;
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_COMMON ,
OPCODE_COMMON_MANAGE_FAT , sizeof ( * req ) ) ;
req - > fat_operation = cpu_to_le32 ( QUERY_FAT ) ;
status = be_mcc_notify_wait ( adapter ) ;
if ( ! status ) {
struct be_cmd_resp_get_fat * resp = embedded_payload ( wrb ) ;
if ( log_size & & resp - > log_size )
2011-04-21 03:18:12 +00:00
* log_size = le32_to_cpu ( resp - > log_size ) -
sizeof ( u32 ) ;
2011-03-16 21:22:43 +00:00
}
err :
spin_unlock_bh ( & adapter - > mcc_lock ) ;
return status ;
}
void be_cmd_get_regs ( struct be_adapter * adapter , u32 buf_len , void * buf )
{
struct be_dma_mem get_fat_cmd ;
struct be_mcc_wrb * wrb ;
struct be_cmd_req_get_fat * req ;
struct be_sge * sge ;
2011-04-21 03:18:12 +00:00
u32 offset = 0 , total_size , buf_size ,
log_offset = sizeof ( u32 ) , payload_len ;
2011-03-16 21:22:43 +00:00
int status ;
if ( buf_len = = 0 )
return ;
total_size = buf_len ;
2011-04-21 03:18:12 +00:00
get_fat_cmd . size = sizeof ( struct be_cmd_req_get_fat ) + 60 * 1024 ;
get_fat_cmd . va = pci_alloc_consistent ( adapter - > pdev ,
get_fat_cmd . size ,
& get_fat_cmd . dma ) ;
if ( ! get_fat_cmd . va ) {
status = - ENOMEM ;
dev_err ( & adapter - > pdev - > dev ,
" Memory allocation failure while retrieving FAT data \n " ) ;
return ;
}
2011-03-16 21:22:43 +00:00
spin_lock_bh ( & adapter - > mcc_lock ) ;
while ( total_size ) {
buf_size = min ( total_size , ( u32 ) 60 * 1024 ) ;
total_size - = buf_size ;
2011-04-21 03:18:12 +00:00
wrb = wrb_from_mccq ( adapter ) ;
if ( ! wrb ) {
status = - EBUSY ;
2011-03-16 21:22:43 +00:00
goto err ;
}
req = get_fat_cmd . va ;
sge = nonembedded_sgl ( wrb ) ;
2011-04-21 03:18:12 +00:00
payload_len = sizeof ( struct be_cmd_req_get_fat ) + buf_size ;
be_wrb_hdr_prepare ( wrb , payload_len , false , 1 ,
2011-03-16 21:22:43 +00:00
OPCODE_COMMON_MANAGE_FAT ) ;
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_COMMON ,
2011-04-21 03:18:12 +00:00
OPCODE_COMMON_MANAGE_FAT , payload_len ) ;
2011-03-16 21:22:43 +00:00
2011-04-21 03:18:12 +00:00
sge - > pa_hi = cpu_to_le32 ( upper_32_bits ( get_fat_cmd . dma ) ) ;
2011-03-16 21:22:43 +00:00
sge - > pa_lo = cpu_to_le32 ( get_fat_cmd . dma & 0xFFFFFFFF ) ;
sge - > len = cpu_to_le32 ( get_fat_cmd . size ) ;
req - > fat_operation = cpu_to_le32 ( RETRIEVE_FAT ) ;
req - > read_log_offset = cpu_to_le32 ( log_offset ) ;
req - > read_log_length = cpu_to_le32 ( buf_size ) ;
req - > data_buffer_size = cpu_to_le32 ( buf_size ) ;
status = be_mcc_notify_wait ( adapter ) ;
if ( ! status ) {
struct be_cmd_resp_get_fat * resp = get_fat_cmd . va ;
memcpy ( buf + offset ,
resp - > data_buffer ,
resp - > read_log_length ) ;
2011-04-21 03:18:12 +00:00
} else {
2011-03-16 21:22:43 +00:00
dev_err ( & adapter - > pdev - > dev , " FAT Table Retrieve error \n " ) ;
2011-04-21 03:18:12 +00:00
goto err ;
}
2011-03-16 21:22:43 +00:00
offset + = buf_size ;
log_offset + = buf_size ;
}
err :
2011-04-21 03:18:12 +00:00
pci_free_consistent ( adapter - > pdev , get_fat_cmd . size ,
get_fat_cmd . va ,
get_fat_cmd . dma ) ;
2011-03-16 21:22:43 +00:00
spin_unlock_bh ( & adapter - > mcc_lock ) ;
}
2009-09-17 10:30:13 -07:00
/* Uses Mbox */
2009-07-27 22:52:03 +00:00
int be_cmd_get_fw_ver ( struct be_adapter * adapter , char * fw_ver )
2009-03-11 23:32:03 -07:00
{
2009-09-17 10:30:13 -07:00
struct be_mcc_wrb * wrb ;
struct be_cmd_req_get_fw_version * req ;
2009-03-11 23:32:03 -07:00
int status ;
2010-12-14 05:43:19 +00:00
if ( mutex_lock_interruptible ( & adapter - > mbox_lock ) )
return - 1 ;
2009-09-17 10:30:13 -07:00
wrb = wrb_from_mbox ( adapter ) ;
req = embedded_payload ( wrb ) ;
2009-03-11 23:32:03 -07:00
2009-12-03 06:12:06 +00:00
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , true , 0 ,
OPCODE_COMMON_GET_FW_VERSION ) ;
2009-03-11 23:32:03 -07:00
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_COMMON ,
OPCODE_COMMON_GET_FW_VERSION , sizeof ( * req ) ) ;
2009-09-17 10:30:13 -07:00
status = be_mbox_notify_wait ( adapter ) ;
2009-03-11 23:32:03 -07:00
if ( ! status ) {
struct be_cmd_resp_get_fw_version * resp = embedded_payload ( wrb ) ;
strncpy ( fw_ver , resp - > firmware_version_string , FW_VER_LEN ) ;
}
2010-12-14 05:43:19 +00:00
mutex_unlock ( & adapter - > mbox_lock ) ;
2009-03-11 23:32:03 -07:00
return status ;
}
2009-09-17 10:30:13 -07:00
/* set the EQ delay interval of an EQ to specified value
* Uses async mcc
*/
2009-07-27 22:52:03 +00:00
int be_cmd_modify_eqd ( struct be_adapter * adapter , u32 eq_id , u32 eqd )
2009-03-11 23:32:03 -07:00
{
2009-09-17 10:30:13 -07:00
struct be_mcc_wrb * wrb ;
struct be_cmd_req_modify_eq_delay * req ;
2009-11-22 22:02:45 +00:00
int status = 0 ;
2009-03-11 23:32:03 -07:00
2009-09-17 10:30:13 -07:00
spin_lock_bh ( & adapter - > mcc_lock ) ;
wrb = wrb_from_mccq ( adapter ) ;
2009-11-22 22:02:45 +00:00
if ( ! wrb ) {
status = - EBUSY ;
goto err ;
}
2009-09-17 10:30:13 -07:00
req = embedded_payload ( wrb ) ;
2009-03-11 23:32:03 -07:00
2009-12-03 06:12:06 +00:00
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , true , 0 ,
OPCODE_COMMON_MODIFY_EQ_DELAY ) ;
2009-03-11 23:32:03 -07:00
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_COMMON ,
OPCODE_COMMON_MODIFY_EQ_DELAY , sizeof ( * req ) ) ;
req - > num_eq = cpu_to_le32 ( 1 ) ;
req - > delay [ 0 ] . eq_id = cpu_to_le32 ( eq_id ) ;
req - > delay [ 0 ] . phase = 0 ;
req - > delay [ 0 ] . delay_multiplier = cpu_to_le32 ( eqd ) ;
2009-09-17 10:30:13 -07:00
be_mcc_notify ( adapter ) ;
2009-03-11 23:32:03 -07:00
2009-11-22 22:02:45 +00:00
err :
2009-09-17 10:30:13 -07:00
spin_unlock_bh ( & adapter - > mcc_lock ) ;
2009-11-22 22:02:45 +00:00
return status ;
2009-03-11 23:32:03 -07:00
}
2009-09-17 10:30:13 -07:00
/* Uses sycnhronous mcc */
2009-07-27 22:52:03 +00:00
int be_cmd_vlan_config ( struct be_adapter * adapter , u32 if_id , u16 * vtag_array ,
2009-03-11 23:32:03 -07:00
u32 num , bool untagged , bool promiscuous )
{
2009-09-17 10:30:13 -07:00
struct be_mcc_wrb * wrb ;
struct be_cmd_req_vlan_config * req ;
2009-03-11 23:32:03 -07:00
int status ;
2009-09-17 10:30:13 -07:00
spin_lock_bh ( & adapter - > mcc_lock ) ;
wrb = wrb_from_mccq ( adapter ) ;
2009-11-22 22:02:45 +00:00
if ( ! wrb ) {
status = - EBUSY ;
goto err ;
}
2009-09-17 10:30:13 -07:00
req = embedded_payload ( wrb ) ;
2009-03-11 23:32:03 -07:00
2009-12-03 06:12:06 +00:00
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , true , 0 ,
OPCODE_COMMON_NTWK_VLAN_CONFIG ) ;
2009-03-11 23:32:03 -07:00
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_COMMON ,
OPCODE_COMMON_NTWK_VLAN_CONFIG , sizeof ( * req ) ) ;
req - > interface_id = if_id ;
req - > promiscuous = promiscuous ;
req - > untagged = untagged ;
req - > num_vlan = num ;
if ( ! promiscuous ) {
memcpy ( req - > normal_vlan , vtag_array ,
req - > num_vlan * sizeof ( vtag_array [ 0 ] ) ) ;
}
2009-09-17 10:30:13 -07:00
status = be_mcc_notify_wait ( adapter ) ;
2009-03-11 23:32:03 -07:00
2009-11-22 22:02:45 +00:00
err :
2009-09-17 10:30:13 -07:00
spin_unlock_bh ( & adapter - > mcc_lock ) ;
2009-03-11 23:32:03 -07:00
return status ;
}
2009-09-17 10:30:13 -07:00
/* Uses MCC for this command as it may be called in BH context
* Uses synchronous mcc
*/
2011-05-10 05:13:26 +00:00
int be_cmd_promiscuous_config ( struct be_adapter * adapter , bool en )
2009-03-11 23:32:03 -07:00
{
2009-06-18 00:05:54 +00:00
struct be_mcc_wrb * wrb ;
2011-05-10 05:13:26 +00:00
struct be_cmd_req_rx_filter * req ;
struct be_dma_mem promiscous_cmd ;
struct be_sge * sge ;
2009-09-17 10:30:13 -07:00
int status ;
2009-03-11 23:32:03 -07:00
2011-05-10 05:13:26 +00:00
memset ( & promiscous_cmd , 0 , sizeof ( struct be_dma_mem ) ) ;
promiscous_cmd . size = sizeof ( struct be_cmd_req_rx_filter ) ;
promiscous_cmd . va = pci_alloc_consistent ( adapter - > pdev ,
promiscous_cmd . size , & promiscous_cmd . dma ) ;
if ( ! promiscous_cmd . va ) {
dev_err ( & adapter - > pdev - > dev ,
" Memory allocation failure \n " ) ;
return - ENOMEM ;
}
2009-07-27 22:52:03 +00:00
spin_lock_bh ( & adapter - > mcc_lock ) ;
2009-06-18 00:05:54 +00:00
2009-09-17 10:30:13 -07:00
wrb = wrb_from_mccq ( adapter ) ;
2009-11-22 22:02:45 +00:00
if ( ! wrb ) {
status = - EBUSY ;
goto err ;
}
2009-03-11 23:32:03 -07:00
2011-05-10 05:13:26 +00:00
req = promiscous_cmd . va ;
sge = nonembedded_sgl ( wrb ) ;
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , false , 1 ,
OPCODE_COMMON_NTWK_RX_FILTER ) ;
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_COMMON ,
OPCODE_COMMON_NTWK_RX_FILTER , sizeof ( * req ) ) ;
req - > if_id = cpu_to_le32 ( adapter - > if_handle ) ;
req - > if_flags_mask = cpu_to_le32 ( BE_IF_FLAGS_PROMISCUOUS ) ;
if ( en )
req - > if_flags = cpu_to_le32 ( BE_IF_FLAGS_PROMISCUOUS ) ;
2009-03-11 23:32:03 -07:00
2011-05-10 05:13:26 +00:00
sge - > pa_hi = cpu_to_le32 ( upper_32_bits ( promiscous_cmd . dma ) ) ;
sge - > pa_lo = cpu_to_le32 ( promiscous_cmd . dma & 0xFFFFFFFF ) ;
sge - > len = cpu_to_le32 ( promiscous_cmd . size ) ;
2009-03-11 23:32:03 -07:00
2009-09-17 10:30:13 -07:00
status = be_mcc_notify_wait ( adapter ) ;
2009-03-11 23:32:03 -07:00
2009-11-22 22:02:45 +00:00
err :
2009-07-27 22:52:03 +00:00
spin_unlock_bh ( & adapter - > mcc_lock ) ;
2011-05-10 05:13:26 +00:00
pci_free_consistent ( adapter - > pdev , promiscous_cmd . size ,
promiscous_cmd . va , promiscous_cmd . dma ) ;
2009-09-17 10:30:13 -07:00
return status ;
2009-03-11 23:32:03 -07:00
}
2009-06-18 00:05:54 +00:00
/*
2009-09-17 10:30:13 -07:00
* Uses MCC for this command as it may be called in BH context
2011-03-30 22:57:33 -03:00
* ( mc = = NULL ) = > multicast promiscuous
2009-06-18 00:05:54 +00:00
*/
2009-07-27 22:52:03 +00:00
int be_cmd_multicast_set ( struct be_adapter * adapter , u32 if_id ,
2010-02-20 00:13:58 +00:00
struct net_device * netdev , struct be_dma_mem * mem )
2009-03-11 23:32:03 -07:00
{
2009-06-18 00:05:54 +00:00
struct be_mcc_wrb * wrb ;
2009-11-22 22:01:10 +00:00
struct be_cmd_req_mcast_mac_config * req = mem - > va ;
struct be_sge * sge ;
int status ;
2009-03-11 23:32:03 -07:00
2009-07-27 22:52:03 +00:00
spin_lock_bh ( & adapter - > mcc_lock ) ;
2009-06-18 00:05:54 +00:00
2009-09-17 10:30:13 -07:00
wrb = wrb_from_mccq ( adapter ) ;
2009-11-22 22:02:45 +00:00
if ( ! wrb ) {
status = - EBUSY ;
goto err ;
}
2009-11-22 22:01:10 +00:00
sge = nonembedded_sgl ( wrb ) ;
memset ( req , 0 , sizeof ( * req ) ) ;
2009-03-11 23:32:03 -07:00
2009-12-03 06:12:06 +00:00
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , false , 1 ,
OPCODE_COMMON_NTWK_MULTICAST_SET ) ;
2009-11-22 22:01:10 +00:00
sge - > pa_hi = cpu_to_le32 ( upper_32_bits ( mem - > dma ) ) ;
sge - > pa_lo = cpu_to_le32 ( mem - > dma & 0xFFFFFFFF ) ;
sge - > len = cpu_to_le32 ( mem - > size ) ;
2009-03-11 23:32:03 -07:00
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_COMMON ,
OPCODE_COMMON_NTWK_MULTICAST_SET , sizeof ( * req ) ) ;
req - > interface_id = if_id ;
2010-02-20 00:13:58 +00:00
if ( netdev ) {
2009-06-18 00:09:25 +00:00
int i ;
2010-04-01 21:22:57 +00:00
struct netdev_hw_addr * ha ;
2009-06-18 00:09:25 +00:00
2010-02-20 00:13:58 +00:00
req - > num_mac = cpu_to_le16 ( netdev_mc_count ( netdev ) ) ;
2009-06-18 00:09:25 +00:00
2010-02-20 00:13:58 +00:00
i = 0 ;
2010-04-01 21:22:57 +00:00
netdev_for_each_mc_addr ( ha , netdev )
2010-12-06 03:00:59 +00:00
memcpy ( req - > mac [ i + + ] . byte , ha - > addr , ETH_ALEN ) ;
2009-06-18 00:09:25 +00:00
} else {
req - > promiscuous = 1 ;
2009-03-11 23:32:03 -07:00
}
2009-11-22 22:01:10 +00:00
status = be_mcc_notify_wait ( adapter ) ;
2009-03-11 23:32:03 -07:00
2009-11-22 22:02:45 +00:00
err :
2009-07-27 22:52:03 +00:00
spin_unlock_bh ( & adapter - > mcc_lock ) ;
2009-11-22 22:01:10 +00:00
return status ;
2009-03-11 23:32:03 -07:00
}
2009-09-17 10:30:13 -07:00
/* Uses synchrounous mcc */
2009-07-27 22:52:03 +00:00
int be_cmd_set_flow_control ( struct be_adapter * adapter , u32 tx_fc , u32 rx_fc )
2009-03-11 23:32:03 -07:00
{
2009-09-17 10:30:13 -07:00
struct be_mcc_wrb * wrb ;
struct be_cmd_req_set_flow_control * req ;
2009-03-11 23:32:03 -07:00
int status ;
2009-09-17 10:30:13 -07:00
spin_lock_bh ( & adapter - > mcc_lock ) ;
2009-03-11 23:32:03 -07:00
2009-09-17 10:30:13 -07:00
wrb = wrb_from_mccq ( adapter ) ;
2009-11-22 22:02:45 +00:00
if ( ! wrb ) {
status = - EBUSY ;
goto err ;
}
2009-09-17 10:30:13 -07:00
req = embedded_payload ( wrb ) ;
2009-03-11 23:32:03 -07:00
2009-12-03 06:12:06 +00:00
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , true , 0 ,
OPCODE_COMMON_SET_FLOW_CONTROL ) ;
2009-03-11 23:32:03 -07:00
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_COMMON ,
OPCODE_COMMON_SET_FLOW_CONTROL , sizeof ( * req ) ) ;
req - > tx_flow_control = cpu_to_le16 ( ( u16 ) tx_fc ) ;
req - > rx_flow_control = cpu_to_le16 ( ( u16 ) rx_fc ) ;
2009-09-17 10:30:13 -07:00
status = be_mcc_notify_wait ( adapter ) ;
2009-03-11 23:32:03 -07:00
2009-11-22 22:02:45 +00:00
err :
2009-09-17 10:30:13 -07:00
spin_unlock_bh ( & adapter - > mcc_lock ) ;
2009-03-11 23:32:03 -07:00
return status ;
}
2009-09-17 10:30:13 -07:00
/* Uses sycn mcc */
2009-07-27 22:52:03 +00:00
int be_cmd_get_flow_control ( struct be_adapter * adapter , u32 * tx_fc , u32 * rx_fc )
2009-03-11 23:32:03 -07:00
{
2009-09-17 10:30:13 -07:00
struct be_mcc_wrb * wrb ;
struct be_cmd_req_get_flow_control * req ;
2009-03-11 23:32:03 -07:00
int status ;
2009-09-17 10:30:13 -07:00
spin_lock_bh ( & adapter - > mcc_lock ) ;
2009-03-11 23:32:03 -07:00
2009-09-17 10:30:13 -07:00
wrb = wrb_from_mccq ( adapter ) ;
2009-11-22 22:02:45 +00:00
if ( ! wrb ) {
status = - EBUSY ;
goto err ;
}
2009-09-17 10:30:13 -07:00
req = embedded_payload ( wrb ) ;
2009-03-11 23:32:03 -07:00
2009-12-03 06:12:06 +00:00
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , true , 0 ,
OPCODE_COMMON_GET_FLOW_CONTROL ) ;
2009-03-11 23:32:03 -07:00
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_COMMON ,
OPCODE_COMMON_GET_FLOW_CONTROL , sizeof ( * req ) ) ;
2009-09-17 10:30:13 -07:00
status = be_mcc_notify_wait ( adapter ) ;
2009-03-11 23:32:03 -07:00
if ( ! status ) {
struct be_cmd_resp_get_flow_control * resp =
embedded_payload ( wrb ) ;
* tx_fc = le16_to_cpu ( resp - > tx_flow_control ) ;
* rx_fc = le16_to_cpu ( resp - > rx_flow_control ) ;
}
2009-11-22 22:02:45 +00:00
err :
2009-09-17 10:30:13 -07:00
spin_unlock_bh ( & adapter - > mcc_lock ) ;
2009-03-11 23:32:03 -07:00
return status ;
}
2009-09-17 10:30:13 -07:00
/* Uses mbox */
2010-10-03 22:12:27 -07:00
int be_cmd_query_fw_cfg ( struct be_adapter * adapter , u32 * port_num ,
u32 * mode , u32 * caps )
2009-03-11 23:32:03 -07:00
{
2009-09-17 10:30:13 -07:00
struct be_mcc_wrb * wrb ;
struct be_cmd_req_query_fw_cfg * req ;
2009-03-11 23:32:03 -07:00
int status ;
2010-12-14 05:43:19 +00:00
if ( mutex_lock_interruptible ( & adapter - > mbox_lock ) )
return - 1 ;
2009-03-11 23:32:03 -07:00
2009-09-17 10:30:13 -07:00
wrb = wrb_from_mbox ( adapter ) ;
req = embedded_payload ( wrb ) ;
2009-03-11 23:32:03 -07:00
2009-12-03 06:12:06 +00:00
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , true , 0 ,
OPCODE_COMMON_QUERY_FIRMWARE_CONFIG ) ;
2009-03-11 23:32:03 -07:00
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_COMMON ,
OPCODE_COMMON_QUERY_FIRMWARE_CONFIG , sizeof ( * req ) ) ;
2009-09-17 10:30:13 -07:00
status = be_mbox_notify_wait ( adapter ) ;
2009-03-11 23:32:03 -07:00
if ( ! status ) {
struct be_cmd_resp_query_fw_cfg * resp = embedded_payload ( wrb ) ;
* port_num = le32_to_cpu ( resp - > phys_port ) ;
2010-07-23 02:04:54 +00:00
* mode = le32_to_cpu ( resp - > function_mode ) ;
2010-10-03 22:12:27 -07:00
* caps = le32_to_cpu ( resp - > function_caps ) ;
2009-03-11 23:32:03 -07:00
}
2010-12-14 05:43:19 +00:00
mutex_unlock ( & adapter - > mbox_lock ) ;
2009-03-11 23:32:03 -07:00
return status ;
}
2009-08-05 13:05:24 -07:00
2009-09-17 10:30:13 -07:00
/* Uses mbox */
2009-08-05 13:05:24 -07:00
int be_cmd_reset_function ( struct be_adapter * adapter )
{
2009-09-17 10:30:13 -07:00
struct be_mcc_wrb * wrb ;
struct be_cmd_req_hdr * req ;
2009-08-05 13:05:24 -07:00
int status ;
2010-12-14 05:43:19 +00:00
if ( mutex_lock_interruptible ( & adapter - > mbox_lock ) )
return - 1 ;
2009-08-05 13:05:24 -07:00
2009-09-17 10:30:13 -07:00
wrb = wrb_from_mbox ( adapter ) ;
req = embedded_payload ( wrb ) ;
2009-08-05 13:05:24 -07:00
2009-12-03 06:12:06 +00:00
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , true , 0 ,
OPCODE_COMMON_FUNCTION_RESET ) ;
2009-08-05 13:05:24 -07:00
be_cmd_hdr_prepare ( req , CMD_SUBSYSTEM_COMMON ,
OPCODE_COMMON_FUNCTION_RESET , sizeof ( * req ) ) ;
2009-09-17 10:30:13 -07:00
status = be_mbox_notify_wait ( adapter ) ;
2009-08-05 13:05:24 -07:00
2010-12-14 05:43:19 +00:00
mutex_unlock ( & adapter - > mbox_lock ) ;
2009-08-05 13:05:24 -07:00
return status ;
}
2009-09-04 03:12:16 +00:00
2010-10-03 22:12:27 -07:00
int be_cmd_rss_config ( struct be_adapter * adapter , u8 * rsstable , u16 table_size )
{
struct be_mcc_wrb * wrb ;
struct be_cmd_req_rss_config * req ;
2011-05-23 20:29:09 +00:00
u32 myhash [ 10 ] = { 0x0123 , 0x4567 , 0x89AB , 0xCDEF , 0x01EF ,
0x0123 , 0x4567 , 0x89AB , 0xCDEF , 0x01EF } ;
2010-10-03 22:12:27 -07:00
int status ;
2010-12-14 05:43:19 +00:00
if ( mutex_lock_interruptible ( & adapter - > mbox_lock ) )
return - 1 ;
2010-10-03 22:12:27 -07:00
wrb = wrb_from_mbox ( adapter ) ;
req = embedded_payload ( wrb ) ;
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , true , 0 ,
OPCODE_ETH_RSS_CONFIG ) ;
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_ETH ,
OPCODE_ETH_RSS_CONFIG , sizeof ( * req ) ) ;
req - > if_id = cpu_to_le32 ( adapter - > if_handle ) ;
req - > enable_rss = cpu_to_le16 ( RSS_ENABLE_TCP_IPV4 | RSS_ENABLE_IPV4 ) ;
req - > cpu_table_size_log2 = cpu_to_le16 ( fls ( table_size ) - 1 ) ;
memcpy ( req - > cpu_table , rsstable , table_size ) ;
memcpy ( req - > hash , myhash , sizeof ( myhash ) ) ;
be_dws_cpu_to_le ( req - > hash , sizeof ( req - > hash ) ) ;
status = be_mbox_notify_wait ( adapter ) ;
2010-12-14 05:43:19 +00:00
mutex_unlock ( & adapter - > mbox_lock ) ;
2010-10-03 22:12:27 -07:00
return status ;
}
2009-10-12 04:23:15 -07:00
/* Uses sync mcc */
int be_cmd_set_beacon_state ( struct be_adapter * adapter , u8 port_num ,
u8 bcn , u8 sts , u8 state )
{
struct be_mcc_wrb * wrb ;
struct be_cmd_req_enable_disable_beacon * req ;
int status ;
spin_lock_bh ( & adapter - > mcc_lock ) ;
wrb = wrb_from_mccq ( adapter ) ;
2009-11-22 22:02:45 +00:00
if ( ! wrb ) {
status = - EBUSY ;
goto err ;
}
2009-10-12 04:23:15 -07:00
req = embedded_payload ( wrb ) ;
2009-12-03 06:12:06 +00:00
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , true , 0 ,
OPCODE_COMMON_ENABLE_DISABLE_BEACON ) ;
2009-10-12 04:23:15 -07:00
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_COMMON ,
OPCODE_COMMON_ENABLE_DISABLE_BEACON , sizeof ( * req ) ) ;
req - > port_num = port_num ;
req - > beacon_state = state ;
req - > beacon_duration = bcn ;
req - > status_duration = sts ;
status = be_mcc_notify_wait ( adapter ) ;
2009-11-22 22:02:45 +00:00
err :
2009-10-12 04:23:15 -07:00
spin_unlock_bh ( & adapter - > mcc_lock ) ;
return status ;
}
/* Uses sync mcc */
int be_cmd_get_beacon_state ( struct be_adapter * adapter , u8 port_num , u32 * state )
{
struct be_mcc_wrb * wrb ;
struct be_cmd_req_get_beacon_state * req ;
int status ;
spin_lock_bh ( & adapter - > mcc_lock ) ;
wrb = wrb_from_mccq ( adapter ) ;
2009-11-22 22:02:45 +00:00
if ( ! wrb ) {
status = - EBUSY ;
goto err ;
}
2009-10-12 04:23:15 -07:00
req = embedded_payload ( wrb ) ;
2009-12-03 06:12:06 +00:00
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , true , 0 ,
OPCODE_COMMON_GET_BEACON_STATE ) ;
2009-10-12 04:23:15 -07:00
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_COMMON ,
OPCODE_COMMON_GET_BEACON_STATE , sizeof ( * req ) ) ;
req - > port_num = port_num ;
status = be_mcc_notify_wait ( adapter ) ;
if ( ! status ) {
struct be_cmd_resp_get_beacon_state * resp =
embedded_payload ( wrb ) ;
* state = resp - > beacon_state ;
}
2009-11-22 22:02:45 +00:00
err :
2009-10-12 04:23:15 -07:00
spin_unlock_bh ( & adapter - > mcc_lock ) ;
return status ;
}
2011-05-16 07:36:59 +00:00
int lancer_cmd_write_object ( struct be_adapter * adapter , struct be_dma_mem * cmd ,
u32 data_size , u32 data_offset , const char * obj_name ,
u32 * data_written , u8 * addn_status )
{
struct be_mcc_wrb * wrb ;
struct lancer_cmd_req_write_object * req ;
struct lancer_cmd_resp_write_object * resp ;
void * ctxt = NULL ;
int status ;
spin_lock_bh ( & adapter - > mcc_lock ) ;
adapter - > flash_status = 0 ;
wrb = wrb_from_mccq ( adapter ) ;
if ( ! wrb ) {
status = - EBUSY ;
goto err_unlock ;
}
req = embedded_payload ( wrb ) ;
be_wrb_hdr_prepare ( wrb , sizeof ( struct lancer_cmd_req_write_object ) ,
true , 1 , OPCODE_COMMON_WRITE_OBJECT ) ;
wrb - > tag1 = CMD_SUBSYSTEM_COMMON ;
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_COMMON ,
OPCODE_COMMON_WRITE_OBJECT ,
sizeof ( struct lancer_cmd_req_write_object ) ) ;
ctxt = & req - > context ;
AMAP_SET_BITS ( struct amap_lancer_write_obj_context ,
write_length , ctxt , data_size ) ;
if ( data_size = = 0 )
AMAP_SET_BITS ( struct amap_lancer_write_obj_context ,
eof , ctxt , 1 ) ;
else
AMAP_SET_BITS ( struct amap_lancer_write_obj_context ,
eof , ctxt , 0 ) ;
be_dws_cpu_to_le ( ctxt , sizeof ( req - > context ) ) ;
req - > write_offset = cpu_to_le32 ( data_offset ) ;
strcpy ( req - > object_name , obj_name ) ;
req - > descriptor_count = cpu_to_le32 ( 1 ) ;
req - > buf_len = cpu_to_le32 ( data_size ) ;
req - > addr_low = cpu_to_le32 ( ( cmd - > dma +
sizeof ( struct lancer_cmd_req_write_object ) )
& 0xFFFFFFFF ) ;
req - > addr_high = cpu_to_le32 ( upper_32_bits ( cmd - > dma +
sizeof ( struct lancer_cmd_req_write_object ) ) ) ;
be_mcc_notify ( adapter ) ;
spin_unlock_bh ( & adapter - > mcc_lock ) ;
if ( ! wait_for_completion_timeout ( & adapter - > flash_compl ,
msecs_to_jiffies ( 12000 ) ) )
status = - 1 ;
else
status = adapter - > flash_status ;
resp = embedded_payload ( wrb ) ;
if ( ! status ) {
* data_written = le32_to_cpu ( resp - > actual_write_len ) ;
} else {
* addn_status = resp - > additional_status ;
status = resp - > status ;
}
return status ;
err_unlock :
spin_unlock_bh ( & adapter - > mcc_lock ) ;
return status ;
}
2009-09-04 03:12:16 +00:00
int be_cmd_write_flashrom ( struct be_adapter * adapter , struct be_dma_mem * cmd ,
u32 flash_type , u32 flash_opcode , u32 buf_size )
{
2009-09-17 10:30:13 -07:00
struct be_mcc_wrb * wrb ;
2010-02-09 01:30:35 +00:00
struct be_cmd_write_flashrom * req ;
2009-09-17 10:30:13 -07:00
struct be_sge * sge ;
2009-09-04 03:12:16 +00:00
int status ;
2009-09-17 10:30:13 -07:00
spin_lock_bh ( & adapter - > mcc_lock ) ;
2010-05-25 16:16:32 -07:00
adapter - > flash_status = 0 ;
2009-09-17 10:30:13 -07:00
wrb = wrb_from_mccq ( adapter ) ;
2009-11-22 22:02:45 +00:00
if ( ! wrb ) {
status = - EBUSY ;
2010-05-26 04:46:35 +00:00
goto err_unlock ;
2009-11-22 22:02:45 +00:00
}
req = cmd - > va ;
2009-09-17 10:30:13 -07:00
sge = nonembedded_sgl ( wrb ) ;
2009-12-03 06:12:06 +00:00
be_wrb_hdr_prepare ( wrb , cmd - > size , false , 1 ,
OPCODE_COMMON_WRITE_FLASHROM ) ;
2010-05-25 16:16:32 -07:00
wrb - > tag1 = CMD_SUBSYSTEM_COMMON ;
2009-09-04 03:12:16 +00:00
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_COMMON ,
OPCODE_COMMON_WRITE_FLASHROM , cmd - > size ) ;
sge - > pa_hi = cpu_to_le32 ( upper_32_bits ( cmd - > dma ) ) ;
sge - > pa_lo = cpu_to_le32 ( cmd - > dma & 0xFFFFFFFF ) ;
sge - > len = cpu_to_le32 ( cmd - > size ) ;
req - > params . op_type = cpu_to_le32 ( flash_type ) ;
req - > params . op_code = cpu_to_le32 ( flash_opcode ) ;
req - > params . data_buf_size = cpu_to_le32 ( buf_size ) ;
2010-05-25 16:16:32 -07:00
be_mcc_notify ( adapter ) ;
spin_unlock_bh ( & adapter - > mcc_lock ) ;
if ( ! wait_for_completion_timeout ( & adapter - > flash_compl ,
msecs_to_jiffies ( 12000 ) ) )
status = - 1 ;
else
status = adapter - > flash_status ;
2009-09-04 03:12:16 +00:00
2010-05-26 04:46:35 +00:00
return status ;
err_unlock :
spin_unlock_bh ( & adapter - > mcc_lock ) ;
2009-09-04 03:12:16 +00:00
return status ;
}
2009-11-20 14:23:47 -08:00
2010-02-09 01:30:35 +00:00
int be_cmd_get_flash_crc ( struct be_adapter * adapter , u8 * flashed_crc ,
int offset )
2009-11-20 14:23:47 -08:00
{
struct be_mcc_wrb * wrb ;
struct be_cmd_write_flashrom * req ;
int status ;
spin_lock_bh ( & adapter - > mcc_lock ) ;
wrb = wrb_from_mccq ( adapter ) ;
2009-11-22 22:02:45 +00:00
if ( ! wrb ) {
status = - EBUSY ;
goto err ;
}
2009-11-20 14:23:47 -08:00
req = embedded_payload ( wrb ) ;
2009-12-03 06:12:06 +00:00
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) + 4 , true , 0 ,
OPCODE_COMMON_READ_FLASHROM ) ;
2009-11-20 14:23:47 -08:00
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_COMMON ,
OPCODE_COMMON_READ_FLASHROM , sizeof ( * req ) + 4 ) ;
2010-02-09 01:30:35 +00:00
req - > params . op_type = cpu_to_le32 ( IMG_TYPE_REDBOOT ) ;
2009-11-20 14:23:47 -08:00
req - > params . op_code = cpu_to_le32 ( FLASHROM_OPER_REPORT ) ;
2010-03-31 01:57:10 +00:00
req - > params . offset = cpu_to_le32 ( offset ) ;
req - > params . data_buf_size = cpu_to_le32 ( 0x4 ) ;
2009-11-20 14:23:47 -08:00
status = be_mcc_notify_wait ( adapter ) ;
if ( ! status )
memcpy ( flashed_crc , req - > params . data_buf , 4 ) ;
2009-11-22 22:02:45 +00:00
err :
2009-11-20 14:23:47 -08:00
spin_unlock_bh ( & adapter - > mcc_lock ) ;
return status ;
}
2009-12-03 06:16:59 +00:00
2010-05-26 04:47:39 +00:00
int be_cmd_enable_magic_wol ( struct be_adapter * adapter , u8 * mac ,
2009-12-03 06:16:59 +00:00
struct be_dma_mem * nonemb_cmd )
{
struct be_mcc_wrb * wrb ;
struct be_cmd_req_acpi_wol_magic_config * req ;
struct be_sge * sge ;
int status ;
spin_lock_bh ( & adapter - > mcc_lock ) ;
wrb = wrb_from_mccq ( adapter ) ;
if ( ! wrb ) {
status = - EBUSY ;
goto err ;
}
req = nonemb_cmd - > va ;
sge = nonembedded_sgl ( wrb ) ;
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , false , 1 ,
OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG ) ;
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_ETH ,
OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG , sizeof ( * req ) ) ;
memcpy ( req - > magic_mac , mac , ETH_ALEN ) ;
sge - > pa_hi = cpu_to_le32 ( upper_32_bits ( nonemb_cmd - > dma ) ) ;
sge - > pa_lo = cpu_to_le32 ( nonemb_cmd - > dma & 0xFFFFFFFF ) ;
sge - > len = cpu_to_le32 ( nonemb_cmd - > size ) ;
status = be_mcc_notify_wait ( adapter ) ;
err :
spin_unlock_bh ( & adapter - > mcc_lock ) ;
return status ;
}
2009-12-03 16:15:52 -08:00
2009-12-23 04:41:44 +00:00
int be_cmd_set_loopback ( struct be_adapter * adapter , u8 port_num ,
u8 loopback_type , u8 enable )
{
struct be_mcc_wrb * wrb ;
struct be_cmd_req_set_lmode * req ;
int status ;
spin_lock_bh ( & adapter - > mcc_lock ) ;
wrb = wrb_from_mccq ( adapter ) ;
if ( ! wrb ) {
status = - EBUSY ;
goto err ;
}
req = embedded_payload ( wrb ) ;
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , true , 0 ,
OPCODE_LOWLEVEL_SET_LOOPBACK_MODE ) ;
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_LOWLEVEL ,
OPCODE_LOWLEVEL_SET_LOOPBACK_MODE ,
sizeof ( * req ) ) ;
req - > src_port = port_num ;
req - > dest_port = port_num ;
req - > loopback_type = loopback_type ;
req - > loopback_state = enable ;
status = be_mcc_notify_wait ( adapter ) ;
err :
spin_unlock_bh ( & adapter - > mcc_lock ) ;
return status ;
}
2009-12-03 16:15:52 -08:00
int be_cmd_loopback_test ( struct be_adapter * adapter , u32 port_num ,
u32 loopback_type , u32 pkt_size , u32 num_pkts , u64 pattern )
{
struct be_mcc_wrb * wrb ;
struct be_cmd_req_loopback_test * req ;
int status ;
spin_lock_bh ( & adapter - > mcc_lock ) ;
wrb = wrb_from_mccq ( adapter ) ;
if ( ! wrb ) {
status = - EBUSY ;
goto err ;
}
req = embedded_payload ( wrb ) ;
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , true , 0 ,
OPCODE_LOWLEVEL_LOOPBACK_TEST ) ;
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_LOWLEVEL ,
OPCODE_LOWLEVEL_LOOPBACK_TEST , sizeof ( * req ) ) ;
2010-06-01 00:19:33 -07:00
req - > hdr . timeout = cpu_to_le32 ( 4 ) ;
2009-12-03 16:15:52 -08:00
req - > pattern = cpu_to_le64 ( pattern ) ;
req - > src_port = cpu_to_le32 ( port_num ) ;
req - > dest_port = cpu_to_le32 ( port_num ) ;
req - > pkt_size = cpu_to_le32 ( pkt_size ) ;
req - > num_pkts = cpu_to_le32 ( num_pkts ) ;
req - > loopback_type = cpu_to_le32 ( loopback_type ) ;
status = be_mcc_notify_wait ( adapter ) ;
if ( ! status ) {
struct be_cmd_resp_loopback_test * resp = embedded_payload ( wrb ) ;
status = le32_to_cpu ( resp - > status ) ;
}
err :
spin_unlock_bh ( & adapter - > mcc_lock ) ;
return status ;
}
int be_cmd_ddr_dma_test ( struct be_adapter * adapter , u64 pattern ,
u32 byte_cnt , struct be_dma_mem * cmd )
{
struct be_mcc_wrb * wrb ;
struct be_cmd_req_ddrdma_test * req ;
struct be_sge * sge ;
int status ;
int i , j = 0 ;
spin_lock_bh ( & adapter - > mcc_lock ) ;
wrb = wrb_from_mccq ( adapter ) ;
if ( ! wrb ) {
status = - EBUSY ;
goto err ;
}
req = cmd - > va ;
sge = nonembedded_sgl ( wrb ) ;
be_wrb_hdr_prepare ( wrb , cmd - > size , false , 1 ,
OPCODE_LOWLEVEL_HOST_DDR_DMA ) ;
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_LOWLEVEL ,
OPCODE_LOWLEVEL_HOST_DDR_DMA , cmd - > size ) ;
sge - > pa_hi = cpu_to_le32 ( upper_32_bits ( cmd - > dma ) ) ;
sge - > pa_lo = cpu_to_le32 ( cmd - > dma & 0xFFFFFFFF ) ;
sge - > len = cpu_to_le32 ( cmd - > size ) ;
req - > pattern = cpu_to_le64 ( pattern ) ;
req - > byte_count = cpu_to_le32 ( byte_cnt ) ;
for ( i = 0 ; i < byte_cnt ; i + + ) {
req - > snd_buff [ i ] = ( u8 ) ( pattern > > ( j * 8 ) ) ;
j + + ;
if ( j > 7 )
j = 0 ;
}
status = be_mcc_notify_wait ( adapter ) ;
if ( ! status ) {
struct be_cmd_resp_ddrdma_test * resp ;
resp = cmd - > va ;
if ( ( memcmp ( resp - > rcv_buff , req - > snd_buff , byte_cnt ) ! = 0 ) | |
resp - > snd_err ) {
status = - 1 ;
}
}
err :
spin_unlock_bh ( & adapter - > mcc_lock ) ;
return status ;
}
2010-01-08 00:07:27 -08:00
2010-05-26 04:47:39 +00:00
int be_cmd_get_seeprom_data ( struct be_adapter * adapter ,
2010-01-08 00:07:27 -08:00
struct be_dma_mem * nonemb_cmd )
{
struct be_mcc_wrb * wrb ;
struct be_cmd_req_seeprom_read * req ;
struct be_sge * sge ;
int status ;
spin_lock_bh ( & adapter - > mcc_lock ) ;
wrb = wrb_from_mccq ( adapter ) ;
2011-02-04 17:18:28 +00:00
if ( ! wrb ) {
status = - EBUSY ;
goto err ;
}
2010-01-08 00:07:27 -08:00
req = nonemb_cmd - > va ;
sge = nonembedded_sgl ( wrb ) ;
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , false , 1 ,
OPCODE_COMMON_SEEPROM_READ ) ;
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_COMMON ,
OPCODE_COMMON_SEEPROM_READ , sizeof ( * req ) ) ;
sge - > pa_hi = cpu_to_le32 ( upper_32_bits ( nonemb_cmd - > dma ) ) ;
sge - > pa_lo = cpu_to_le32 ( nonemb_cmd - > dma & 0xFFFFFFFF ) ;
sge - > len = cpu_to_le32 ( nonemb_cmd - > size ) ;
status = be_mcc_notify_wait ( adapter ) ;
2011-02-04 17:18:28 +00:00
err :
2010-01-08 00:07:27 -08:00
spin_unlock_bh ( & adapter - > mcc_lock ) ;
return status ;
}
2010-07-01 03:51:00 +00:00
int be_cmd_get_phy_info ( struct be_adapter * adapter , struct be_dma_mem * cmd )
{
struct be_mcc_wrb * wrb ;
struct be_cmd_req_get_phy_info * req ;
struct be_sge * sge ;
int status ;
spin_lock_bh ( & adapter - > mcc_lock ) ;
wrb = wrb_from_mccq ( adapter ) ;
if ( ! wrb ) {
status = - EBUSY ;
goto err ;
}
req = cmd - > va ;
sge = nonembedded_sgl ( wrb ) ;
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , false , 1 ,
OPCODE_COMMON_GET_PHY_DETAILS ) ;
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_COMMON ,
OPCODE_COMMON_GET_PHY_DETAILS ,
sizeof ( * req ) ) ;
sge - > pa_hi = cpu_to_le32 ( upper_32_bits ( cmd - > dma ) ) ;
sge - > pa_lo = cpu_to_le32 ( cmd - > dma & 0xFFFFFFFF ) ;
sge - > len = cpu_to_le32 ( cmd - > size ) ;
status = be_mcc_notify_wait ( adapter ) ;
err :
spin_unlock_bh ( & adapter - > mcc_lock ) ;
return status ;
}
2010-07-23 01:52:13 +00:00
int be_cmd_set_qos ( struct be_adapter * adapter , u32 bps , u32 domain )
{
struct be_mcc_wrb * wrb ;
struct be_cmd_req_set_qos * req ;
int status ;
spin_lock_bh ( & adapter - > mcc_lock ) ;
wrb = wrb_from_mccq ( adapter ) ;
if ( ! wrb ) {
status = - EBUSY ;
goto err ;
}
req = embedded_payload ( wrb ) ;
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , true , 0 ,
OPCODE_COMMON_SET_QOS ) ;
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_COMMON ,
OPCODE_COMMON_SET_QOS , sizeof ( * req ) ) ;
req - > hdr . domain = domain ;
2011-02-11 13:33:02 +00:00
req - > valid_bits = cpu_to_le32 ( BE_QOS_BITS_NIC ) ;
req - > max_bps_nic = cpu_to_le32 ( bps ) ;
2010-07-23 01:52:13 +00:00
status = be_mcc_notify_wait ( adapter ) ;
err :
spin_unlock_bh ( & adapter - > mcc_lock ) ;
return status ;
}
2011-02-20 11:42:22 +00:00
int be_cmd_get_cntl_attributes ( struct be_adapter * adapter )
{
struct be_mcc_wrb * wrb ;
struct be_cmd_req_cntl_attribs * req ;
struct be_cmd_resp_cntl_attribs * resp ;
struct be_sge * sge ;
int status ;
int payload_len = max ( sizeof ( * req ) , sizeof ( * resp ) ) ;
struct mgmt_controller_attrib * attribs ;
struct be_dma_mem attribs_cmd ;
memset ( & attribs_cmd , 0 , sizeof ( struct be_dma_mem ) ) ;
attribs_cmd . size = sizeof ( struct be_cmd_resp_cntl_attribs ) ;
attribs_cmd . va = pci_alloc_consistent ( adapter - > pdev , attribs_cmd . size ,
& attribs_cmd . dma ) ;
if ( ! attribs_cmd . va ) {
dev_err ( & adapter - > pdev - > dev ,
" Memory allocation failure \n " ) ;
return - ENOMEM ;
}
if ( mutex_lock_interruptible ( & adapter - > mbox_lock ) )
return - 1 ;
wrb = wrb_from_mbox ( adapter ) ;
if ( ! wrb ) {
status = - EBUSY ;
goto err ;
}
req = attribs_cmd . va ;
sge = nonembedded_sgl ( wrb ) ;
be_wrb_hdr_prepare ( wrb , payload_len , false , 1 ,
OPCODE_COMMON_GET_CNTL_ATTRIBUTES ) ;
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_COMMON ,
OPCODE_COMMON_GET_CNTL_ATTRIBUTES , payload_len ) ;
sge - > pa_hi = cpu_to_le32 ( upper_32_bits ( attribs_cmd . dma ) ) ;
sge - > pa_lo = cpu_to_le32 ( attribs_cmd . dma & 0xFFFFFFFF ) ;
sge - > len = cpu_to_le32 ( attribs_cmd . size ) ;
status = be_mbox_notify_wait ( adapter ) ;
if ( ! status ) {
2011-06-16 19:08:06 +00:00
attribs = attribs_cmd . va + sizeof ( struct be_cmd_resp_hdr ) ;
2011-02-20 11:42:22 +00:00
adapter - > hba_port_num = attribs - > hba_attribs . phy_port ;
}
err :
mutex_unlock ( & adapter - > mbox_lock ) ;
pci_free_consistent ( adapter - > pdev , attribs_cmd . size , attribs_cmd . va ,
attribs_cmd . dma ) ;
return status ;
}
2011-03-11 02:49:26 +00:00
/* Uses mbox */
2011-07-19 19:52:33 +00:00
int be_cmd_req_native_mode ( struct be_adapter * adapter )
2011-03-11 02:49:26 +00:00
{
struct be_mcc_wrb * wrb ;
struct be_cmd_req_set_func_cap * req ;
int status ;
if ( mutex_lock_interruptible ( & adapter - > mbox_lock ) )
return - 1 ;
wrb = wrb_from_mbox ( adapter ) ;
if ( ! wrb ) {
status = - EBUSY ;
goto err ;
}
req = embedded_payload ( wrb ) ;
be_wrb_hdr_prepare ( wrb , sizeof ( * req ) , true , 0 ,
OPCODE_COMMON_SET_DRIVER_FUNCTION_CAP ) ;
be_cmd_hdr_prepare ( & req - > hdr , CMD_SUBSYSTEM_COMMON ,
OPCODE_COMMON_SET_DRIVER_FUNCTION_CAP , sizeof ( * req ) ) ;
req - > valid_cap_flags = cpu_to_le32 ( CAPABILITY_SW_TIMESTAMPS |
CAPABILITY_BE3_NATIVE_ERX_API ) ;
req - > cap_flags = cpu_to_le32 ( CAPABILITY_BE3_NATIVE_ERX_API ) ;
status = be_mbox_notify_wait ( adapter ) ;
if ( ! status ) {
struct be_cmd_resp_set_func_cap * resp = embedded_payload ( wrb ) ;
adapter - > be3_native = le32_to_cpu ( resp - > cap_flags ) &
CAPABILITY_BE3_NATIVE_ERX_API ;
}
err :
mutex_unlock ( & adapter - > mbox_lock ) ;
return status ;
}