Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
此提交包含在:
@@ -803,6 +803,12 @@ enum {
|
||||
MB_CMD_SET_PORT_CFG = 0x00000122,
|
||||
MB_CMD_GET_PORT_CFG = 0x00000123,
|
||||
MB_CMD_GET_LINK_STS = 0x00000124,
|
||||
MB_CMD_SET_MGMNT_TFK_CTL = 0x00000160, /* Set Mgmnt Traffic Control */
|
||||
MB_SET_MPI_TFK_STOP = (1 << 0),
|
||||
MB_SET_MPI_TFK_RESUME = (1 << 1),
|
||||
MB_CMD_GET_MGMNT_TFK_CTL = 0x00000161, /* Get Mgmnt Traffic Control */
|
||||
MB_GET_MPI_TFK_STOPPED = (1 << 0),
|
||||
MB_GET_MPI_TFK_FIFO_EMPTY = (1 << 1),
|
||||
|
||||
/* Mailbox Command Status. */
|
||||
MB_CMD_STS_GOOD = 0x00004000, /* Success. */
|
||||
@@ -1168,7 +1174,7 @@ struct ricb {
|
||||
#define RSS_RI6 0x40
|
||||
#define RSS_RT6 0x80
|
||||
__le16 mask;
|
||||
__le32 hash_cq_id[256];
|
||||
u8 hash_cq_id[1024];
|
||||
__le32 ipv6_hash_key[10];
|
||||
__le32 ipv4_hash_key[4];
|
||||
} __attribute((packed));
|
||||
@@ -1605,6 +1611,8 @@ int ql_read_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 *data);
|
||||
int ql_mb_about_fw(struct ql_adapter *qdev);
|
||||
void ql_link_on(struct ql_adapter *qdev);
|
||||
void ql_link_off(struct ql_adapter *qdev);
|
||||
int ql_mb_set_mgmnt_traffic_ctl(struct ql_adapter *qdev, u32 control);
|
||||
int ql_wait_fifo_empty(struct ql_adapter *qdev);
|
||||
|
||||
#if 1
|
||||
#define QL_ALL_DUMP
|
||||
|
@@ -320,6 +320,37 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type,
|
||||
|
||||
switch (type) {
|
||||
case MAC_ADDR_TYPE_MULTI_MAC:
|
||||
{
|
||||
u32 upper = (addr[0] << 8) | addr[1];
|
||||
u32 lower = (addr[2] << 24) | (addr[3] << 16) |
|
||||
(addr[4] << 8) | (addr[5]);
|
||||
|
||||
status =
|
||||
ql_wait_reg_rdy(qdev,
|
||||
MAC_ADDR_IDX, MAC_ADDR_MW, 0);
|
||||
if (status)
|
||||
goto exit;
|
||||
ql_write32(qdev, MAC_ADDR_IDX, (offset++) |
|
||||
(index << MAC_ADDR_IDX_SHIFT) |
|
||||
type | MAC_ADDR_E);
|
||||
ql_write32(qdev, MAC_ADDR_DATA, lower);
|
||||
status =
|
||||
ql_wait_reg_rdy(qdev,
|
||||
MAC_ADDR_IDX, MAC_ADDR_MW, 0);
|
||||
if (status)
|
||||
goto exit;
|
||||
ql_write32(qdev, MAC_ADDR_IDX, (offset++) |
|
||||
(index << MAC_ADDR_IDX_SHIFT) |
|
||||
type | MAC_ADDR_E);
|
||||
|
||||
ql_write32(qdev, MAC_ADDR_DATA, upper);
|
||||
status =
|
||||
ql_wait_reg_rdy(qdev,
|
||||
MAC_ADDR_IDX, MAC_ADDR_MW, 0);
|
||||
if (status)
|
||||
goto exit;
|
||||
break;
|
||||
}
|
||||
case MAC_ADDR_TYPE_CAM_MAC:
|
||||
{
|
||||
u32 cam_output;
|
||||
@@ -365,16 +396,14 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type,
|
||||
and possibly the function id. Right now we hardcode
|
||||
the route field to NIC core.
|
||||
*/
|
||||
if (type == MAC_ADDR_TYPE_CAM_MAC) {
|
||||
cam_output = (CAM_OUT_ROUTE_NIC |
|
||||
(qdev->
|
||||
func << CAM_OUT_FUNC_SHIFT) |
|
||||
(0 << CAM_OUT_CQ_ID_SHIFT));
|
||||
if (qdev->vlgrp)
|
||||
cam_output |= CAM_OUT_RV;
|
||||
/* route to NIC core */
|
||||
ql_write32(qdev, MAC_ADDR_DATA, cam_output);
|
||||
}
|
||||
cam_output = (CAM_OUT_ROUTE_NIC |
|
||||
(qdev->
|
||||
func << CAM_OUT_FUNC_SHIFT) |
|
||||
(0 << CAM_OUT_CQ_ID_SHIFT));
|
||||
if (qdev->vlgrp)
|
||||
cam_output |= CAM_OUT_RV;
|
||||
/* route to NIC core */
|
||||
ql_write32(qdev, MAC_ADDR_DATA, cam_output);
|
||||
break;
|
||||
}
|
||||
case MAC_ADDR_TYPE_VLAN:
|
||||
@@ -546,14 +575,14 @@ static int ql_set_routing_reg(struct ql_adapter *qdev, u32 index, u32 mask,
|
||||
}
|
||||
case RT_IDX_MCAST: /* Pass up All Multicast frames. */
|
||||
{
|
||||
value = RT_IDX_DST_CAM_Q | /* dest */
|
||||
value = RT_IDX_DST_DFLT_Q | /* dest */
|
||||
RT_IDX_TYPE_NICQ | /* type */
|
||||
(RT_IDX_ALLMULTI_SLOT << RT_IDX_IDX_SHIFT);/* index */
|
||||
break;
|
||||
}
|
||||
case RT_IDX_MCAST_MATCH: /* Pass up matched Multicast frames. */
|
||||
{
|
||||
value = RT_IDX_DST_CAM_Q | /* dest */
|
||||
value = RT_IDX_DST_DFLT_Q | /* dest */
|
||||
RT_IDX_TYPE_NICQ | /* type */
|
||||
(RT_IDX_MCAST_MATCH_SLOT << RT_IDX_IDX_SHIFT);/* index */
|
||||
break;
|
||||
@@ -3078,6 +3107,12 @@ err_irq:
|
||||
|
||||
static int ql_start_rss(struct ql_adapter *qdev)
|
||||
{
|
||||
u8 init_hash_seed[] = {0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2,
|
||||
0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f,
|
||||
0xb0, 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b,
|
||||
0x30, 0xb4, 0x77, 0xcb, 0x2d, 0xa3, 0x80,
|
||||
0x30, 0xf2, 0x0c, 0x6a, 0x42, 0xb7, 0x3b,
|
||||
0xbe, 0xac, 0x01, 0xfa};
|
||||
struct ricb *ricb = &qdev->ricb;
|
||||
int status = 0;
|
||||
int i;
|
||||
@@ -3087,21 +3122,17 @@ static int ql_start_rss(struct ql_adapter *qdev)
|
||||
|
||||
ricb->base_cq = RSS_L4K;
|
||||
ricb->flags =
|
||||
(RSS_L6K | RSS_LI | RSS_LB | RSS_LM | RSS_RI4 | RSS_RI6 | RSS_RT4 |
|
||||
RSS_RT6);
|
||||
ricb->mask = cpu_to_le16(qdev->rss_ring_count - 1);
|
||||
(RSS_L6K | RSS_LI | RSS_LB | RSS_LM | RSS_RT4 | RSS_RT6);
|
||||
ricb->mask = cpu_to_le16((u16)(0x3ff));
|
||||
|
||||
/*
|
||||
* Fill out the Indirection Table.
|
||||
*/
|
||||
for (i = 0; i < 256; i++)
|
||||
hash_id[i] = i & (qdev->rss_ring_count - 1);
|
||||
for (i = 0; i < 1024; i++)
|
||||
hash_id[i] = (i & (qdev->rss_ring_count - 1));
|
||||
|
||||
/*
|
||||
* Random values for the IPv6 and IPv4 Hash Keys.
|
||||
*/
|
||||
get_random_bytes((void *)&ricb->ipv6_hash_key[0], 40);
|
||||
get_random_bytes((void *)&ricb->ipv4_hash_key[0], 16);
|
||||
memcpy((void *)&ricb->ipv6_hash_key[0], init_hash_seed, 40);
|
||||
memcpy((void *)&ricb->ipv4_hash_key[0], init_hash_seed, 16);
|
||||
|
||||
QPRINTK(qdev, IFUP, DEBUG, "Initializing RSS.\n");
|
||||
|
||||
@@ -3240,6 +3271,13 @@ static int ql_adapter_initialize(struct ql_adapter *qdev)
|
||||
ql_write32(qdev, SPLT_HDR, SPLT_HDR_EP |
|
||||
min(SMALL_BUFFER_SIZE, MAX_SPLIT_SIZE));
|
||||
|
||||
/* Set RX packet routing to use port/pci function on which the
|
||||
* packet arrived on in addition to usual frame routing.
|
||||
* This is helpful on bonding where both interfaces can have
|
||||
* the same MAC address.
|
||||
*/
|
||||
ql_write32(qdev, RST_FO, RST_FO_RR_MASK | RST_FO_RR_RCV_FUNC_CQ);
|
||||
|
||||
/* Start up the rx queues. */
|
||||
for (i = 0; i < qdev->rx_ring_count; i++) {
|
||||
status = ql_start_rx_ring(qdev, &qdev->rx_ring[i]);
|
||||
@@ -3312,6 +3350,13 @@ static int ql_adapter_reset(struct ql_adapter *qdev)
|
||||
|
||||
end_jiffies = jiffies +
|
||||
max((unsigned long)1, usecs_to_jiffies(30));
|
||||
|
||||
/* Stop management traffic. */
|
||||
ql_mb_set_mgmnt_traffic_ctl(qdev, MB_SET_MPI_TFK_STOP);
|
||||
|
||||
/* Wait for the NIC and MGMNT FIFOs to empty. */
|
||||
ql_wait_fifo_empty(qdev);
|
||||
|
||||
ql_write32(qdev, RST_FO, (RST_FO_FR << 16) | RST_FO_FR);
|
||||
|
||||
do {
|
||||
@@ -3327,6 +3372,8 @@ static int ql_adapter_reset(struct ql_adapter *qdev)
|
||||
status = -ETIMEDOUT;
|
||||
}
|
||||
|
||||
/* Resume management traffic. */
|
||||
ql_mb_set_mgmnt_traffic_ctl(qdev, MB_SET_MPI_TFK_RESUME);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -3704,6 +3751,12 @@ static void ql_asic_reset_work(struct work_struct *work)
|
||||
status = ql_adapter_up(qdev);
|
||||
if (status)
|
||||
goto error;
|
||||
|
||||
/* Restore rx mode. */
|
||||
clear_bit(QL_ALLMULTI, &qdev->flags);
|
||||
clear_bit(QL_PROMISCUOUS, &qdev->flags);
|
||||
qlge_set_multicast_list(qdev->ndev);
|
||||
|
||||
rtnl_unlock();
|
||||
return;
|
||||
error:
|
||||
|
@@ -768,6 +768,95 @@ static int ql_idc_wait(struct ql_adapter *qdev)
|
||||
return status;
|
||||
}
|
||||
|
||||
int ql_mb_set_mgmnt_traffic_ctl(struct ql_adapter *qdev, u32 control)
|
||||
{
|
||||
struct mbox_params mbc;
|
||||
struct mbox_params *mbcp = &mbc;
|
||||
int status;
|
||||
|
||||
memset(mbcp, 0, sizeof(struct mbox_params));
|
||||
|
||||
mbcp->in_count = 1;
|
||||
mbcp->out_count = 2;
|
||||
|
||||
mbcp->mbox_in[0] = MB_CMD_SET_MGMNT_TFK_CTL;
|
||||
mbcp->mbox_in[1] = control;
|
||||
|
||||
status = ql_mailbox_command(qdev, mbcp);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (mbcp->mbox_out[0] == MB_CMD_STS_GOOD)
|
||||
return status;
|
||||
|
||||
if (mbcp->mbox_out[0] == MB_CMD_STS_INVLD_CMD) {
|
||||
QPRINTK(qdev, DRV, ERR,
|
||||
"Command not supported by firmware.\n");
|
||||
status = -EINVAL;
|
||||
} else if (mbcp->mbox_out[0] == MB_CMD_STS_ERR) {
|
||||
/* This indicates that the firmware is
|
||||
* already in the state we are trying to
|
||||
* change it to.
|
||||
*/
|
||||
QPRINTK(qdev, DRV, ERR,
|
||||
"Command parameters make no change.\n");
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Returns a negative error code or the mailbox command status. */
|
||||
static int ql_mb_get_mgmnt_traffic_ctl(struct ql_adapter *qdev, u32 *control)
|
||||
{
|
||||
struct mbox_params mbc;
|
||||
struct mbox_params *mbcp = &mbc;
|
||||
int status;
|
||||
|
||||
memset(mbcp, 0, sizeof(struct mbox_params));
|
||||
*control = 0;
|
||||
|
||||
mbcp->in_count = 1;
|
||||
mbcp->out_count = 1;
|
||||
|
||||
mbcp->mbox_in[0] = MB_CMD_GET_MGMNT_TFK_CTL;
|
||||
|
||||
status = ql_mailbox_command(qdev, mbcp);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (mbcp->mbox_out[0] == MB_CMD_STS_GOOD) {
|
||||
*control = mbcp->mbox_in[1];
|
||||
return status;
|
||||
}
|
||||
|
||||
if (mbcp->mbox_out[0] == MB_CMD_STS_INVLD_CMD) {
|
||||
QPRINTK(qdev, DRV, ERR,
|
||||
"Command not supported by firmware.\n");
|
||||
status = -EINVAL;
|
||||
} else if (mbcp->mbox_out[0] == MB_CMD_STS_ERR) {
|
||||
QPRINTK(qdev, DRV, ERR,
|
||||
"Failed to get MPI traffic control.\n");
|
||||
status = -EIO;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
int ql_wait_fifo_empty(struct ql_adapter *qdev)
|
||||
{
|
||||
int count = 5;
|
||||
u32 mgmnt_fifo_empty;
|
||||
u32 nic_fifo_empty;
|
||||
|
||||
do {
|
||||
nic_fifo_empty = ql_read32(qdev, STS) & STS_NFE;
|
||||
ql_mb_get_mgmnt_traffic_ctl(qdev, &mgmnt_fifo_empty);
|
||||
mgmnt_fifo_empty &= MB_GET_MPI_TFK_FIFO_EMPTY;
|
||||
if (nic_fifo_empty && mgmnt_fifo_empty)
|
||||
return 0;
|
||||
msleep(100);
|
||||
} while (count-- > 0);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
/* API called in work thread context to set new TX/RX
|
||||
* maximum frame size values to match MTU.
|
||||
*/
|
||||
@@ -876,6 +965,8 @@ void ql_mpi_work(struct work_struct *work)
|
||||
int err = 0;
|
||||
|
||||
rtnl_lock();
|
||||
/* Begin polled mode for MPI */
|
||||
ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16));
|
||||
|
||||
while (ql_read32(qdev, STS) & STS_PI) {
|
||||
memset(mbcp, 0, sizeof(struct mbox_params));
|
||||
@@ -888,6 +979,8 @@ void ql_mpi_work(struct work_struct *work)
|
||||
break;
|
||||
}
|
||||
|
||||
/* End polled mode for MPI */
|
||||
ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI);
|
||||
rtnl_unlock();
|
||||
ql_enable_completion_interrupt(qdev, 0);
|
||||
}
|
||||
|
新增問題並參考
封鎖使用者