HOSTCC_MODE_ENABLE | tnapi->coal_now);
}
-static void tg3_napi_disable(struct tg3 *tp)
-{
- int i;
-
- for (i = tp->irq_cnt - 1; i >= 0; i--)
- napi_disable(&tp->napi[i].napi);
-}
-
-static void tg3_napi_enable(struct tg3 *tp)
-{
- int i;
-
- for (i = 0; i < tp->irq_cnt; i++)
- napi_enable(&tp->napi[i].napi);
-}
-
-static inline void tg3_netif_stop(struct tg3 *tp)
-{
- tp->dev->trans_start = jiffies; /* prevent tx timeout */
- tg3_napi_disable(tp);
- netif_tx_disable(tp->dev);
-}
-
-static inline void tg3_netif_start(struct tg3 *tp)
-{
- /* NOTE: unconditional netif_tx_wake_all_queues is only
- * appropriate so long as all callers are assured to
- * have free tx slots (such as after tg3_init_hw)
- */
- netif_tx_wake_all_queues(tp->dev);
-
- tg3_napi_enable(tp);
- tp->napi[0].hw_status->status |= SD_STATUS_UPDATED;
- tg3_enable_ints(tp);
-}
-
static void tg3_switch_clocks(struct tg3 *tp)
{
u32 clock_ctrl;
*/
static int tg3_phy_reset(struct tg3 *tp)
{
- u32 cpmuctrl;
- u32 phy_status;
+ u32 val, cpmuctrl;
int err;
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
- u32 val;
-
val = tr32(GRC_MISC_CFG);
tw32_f(GRC_MISC_CFG, val & ~GRC_MISC_CFG_EPHY_IDDQ);
udelay(40);
}
- err = tg3_readphy(tp, MII_BMSR, &phy_status);
- err |= tg3_readphy(tp, MII_BMSR, &phy_status);
+ err = tg3_readphy(tp, MII_BMSR, &val);
+ err |= tg3_readphy(tp, MII_BMSR, &val);
if (err != 0)
return -EBUSY;
return err;
if (cpmuctrl & CPMU_CTRL_GPHY_10MB_RXONLY) {
- u32 phy;
-
- phy = MII_TG3_DSP_EXP8_AEDW | MII_TG3_DSP_EXP8_REJ2MHz;
- tg3_phydsp_write(tp, MII_TG3_DSP_EXP8, phy);
+ val = MII_TG3_DSP_EXP8_AEDW | MII_TG3_DSP_EXP8_REJ2MHz;
+ tg3_phydsp_write(tp, MII_TG3_DSP_EXP8, val);
tw32(TG3_CPMU_CTRL, cpmuctrl);
}
if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5784_AX ||
GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5761_AX) {
- u32 val;
-
val = tr32(TG3_CPMU_LSPD_1000MB_CLK);
if ((val & CPMU_LSPD_1000MB_MACCLK_MASK) ==
CPMU_LSPD_1000MB_MACCLK_12_5) {
/* Cannot do read-modify-write on 5401 */
tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4c20);
} else if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
- u32 phy_reg;
-
/* Set bit 14 with read-modify-write to preserve other bits */
if (!tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0007) &&
- !tg3_readphy(tp, MII_TG3_AUX_CTRL, &phy_reg))
- tg3_writephy(tp, MII_TG3_AUX_CTRL, phy_reg | 0x4000);
+ !tg3_readphy(tp, MII_TG3_AUX_CTRL, &val))
+ tg3_writephy(tp, MII_TG3_AUX_CTRL, val | 0x4000);
}
/* Set phy register 0x10 bit 0 to high fifo elasticity to support
* jumbo frames transmission.
*/
if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
- u32 phy_reg;
-
- if (!tg3_readphy(tp, MII_TG3_EXT_CTRL, &phy_reg))
+ if (!tg3_readphy(tp, MII_TG3_EXT_CTRL, &val))
tg3_writephy(tp, MII_TG3_EXT_CTRL,
- phy_reg | MII_TG3_EXT_CTRL_FIFO_ELASTIC);
+ val | MII_TG3_EXT_CTRL_FIFO_ELASTIC);
}
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset)
{
int current_link_up;
- u32 bmsr, dummy;
+ u32 bmsr, val;
u32 lcl_adv, rmt_adv;
u16 current_speed;
u8 current_duplex;
}
/* Clear pending interrupts... */
- tg3_readphy(tp, MII_TG3_ISTAT, &dummy);
- tg3_readphy(tp, MII_TG3_ISTAT, &dummy);
+ tg3_readphy(tp, MII_TG3_ISTAT, &val);
+ tg3_readphy(tp, MII_TG3_ISTAT, &val);
if (tp->phy_flags & TG3_PHYFLG_USE_MI_INTERRUPT)
tg3_writephy(tp, MII_TG3_IMASK, ~MII_TG3_INT_LINKCHG);
current_duplex = DUPLEX_INVALID;
if (tp->phy_flags & TG3_PHYFLG_CAPACITIVE_COUPLING) {
- u32 val;
-
tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4007);
tg3_readphy(tp, MII_TG3_AUX_CTRL, &val);
if (!(val & (1 << 10))) {
relink:
if (current_link_up == 0 || (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)) {
- u32 tmp;
-
tg3_phy_copper_begin(tp);
- tg3_readphy(tp, MII_BMSR, &tmp);
- if (!tg3_readphy(tp, MII_BMSR, &tmp) &&
- (tmp & BMSR_LSTATUS))
+ tg3_readphy(tp, MII_BMSR, &bmsr);
+ if (!tg3_readphy(tp, MII_BMSR, &bmsr) &&
+ (bmsr & BMSR_LSTATUS))
current_link_up = 1;
}
return err;
}
+static inline int tg3_irq_sync(struct tg3 *tp)
+{
+ return tp->irq_sync;
+}
+
/* This is called whenever we suspect that the system chipset is re-
* ordering the sequence of MMIO to the tx send mailbox. The symptom
* is bogus tx completions. We try to recover by setting the
struct tg3 *tp = tnapi->tp;
struct tg3_rx_buffer_desc *src_desc, *dest_desc;
struct ring_info *src_map, *dest_map;
- struct tg3_rx_prodring_set *spr = &tp->prodring[0];
+ struct tg3_rx_prodring_set *spr = &tp->napi[0].prodring;
int dest_idx;
switch (opaque_key) {
u32 sw_idx = tnapi->rx_rcb_ptr;
u16 hw_idx;
int received;
- struct tg3_rx_prodring_set *tpr = tnapi->prodring;
+ struct tg3_rx_prodring_set *tpr = &tnapi->prodring;
hw_idx = *(tnapi->rx_rcb_prod_idx);
/*
desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK;
opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK;
if (opaque_key == RXD_OPAQUE_RING_STD) {
- ri = &tp->prodring[0].rx_std_buffers[desc_idx];
+ ri = &tp->napi[0].prodring.rx_std_buffers[desc_idx];
dma_addr = dma_unmap_addr(ri, mapping);
skb = ri->skb;
post_ptr = &std_prod_idx;
rx_std_posted++;
} else if (opaque_key == RXD_OPAQUE_RING_JUMBO) {
- ri = &tp->prodring[0].rx_jmb_buffers[desc_idx];
+ ri = &tp->napi[0].prodring.rx_jmb_buffers[desc_idx];
dma_addr = dma_unmap_addr(ri, mapping);
skb = ri->skb;
post_ptr = &jmb_prod_idx;
work_done += tg3_rx(tnapi, budget - work_done);
if ((tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS) && tnapi == &tp->napi[1]) {
- struct tg3_rx_prodring_set *dpr = &tp->prodring[0];
+ struct tg3_rx_prodring_set *dpr = &tp->napi[0].prodring;
int i, err = 0;
u32 std_prod_idx = dpr->rx_std_prod_idx;
u32 jmb_prod_idx = dpr->rx_jmb_prod_idx;
for (i = 1; i < tp->irq_cnt; i++)
err |= tg3_rx_prodring_xfer(tp, dpr,
- tp->napi[i].prodring);
+ &tp->napi[i].prodring);
wmb();
return work_done;
}
+static void tg3_napi_disable(struct tg3 *tp)
+{
+ int i;
+
+ for (i = tp->irq_cnt - 1; i >= 0; i--)
+ napi_disable(&tp->napi[i].napi);
+}
+
+static void tg3_napi_enable(struct tg3 *tp)
+{
+ int i;
+
+ for (i = 0; i < tp->irq_cnt; i++)
+ napi_enable(&tp->napi[i].napi);
+}
+
+static void tg3_napi_init(struct tg3 *tp)
+{
+ int i;
+
+ netif_napi_add(tp->dev, &tp->napi[0].napi, tg3_poll, 64);
+ for (i = 1; i < tp->irq_cnt; i++)
+ netif_napi_add(tp->dev, &tp->napi[i].napi, tg3_poll_msix, 64);
+}
+
+static void tg3_napi_fini(struct tg3 *tp)
+{
+ int i;
+
+ for (i = 0; i < tp->irq_cnt; i++)
+ netif_napi_del(&tp->napi[i].napi);
+}
+
+static inline void tg3_netif_stop(struct tg3 *tp)
+{
+ tp->dev->trans_start = jiffies; /* prevent tx timeout */
+ tg3_napi_disable(tp);
+ netif_tx_disable(tp->dev);
+}
+
+static inline void tg3_netif_start(struct tg3 *tp)
+{
+ /* NOTE: unconditional netif_tx_wake_all_queues is only
+ * appropriate so long as all callers are assured to
+ * have free tx slots (such as after tg3_init_hw)
+ */
+ netif_tx_wake_all_queues(tp->dev);
+
+ tg3_napi_enable(tp);
+ tp->napi[0].hw_status->status |= SD_STATUS_UPDATED;
+ tg3_enable_ints(tp);
+}
+
static void tg3_irq_quiesce(struct tg3 *tp)
{
int i;
synchronize_irq(tp->napi[i].irq_vec);
}
-static inline int tg3_irq_sync(struct tg3 *tp)
-{
- return tp->irq_sync;
-}
-
/* Fully shutdown all tg3 driver activity elsewhere in the system.
* If irq_sync is non-zero, then the IRQ handler must be synchronized
* with as well. Most of the time, this is not necessary except when
{
u32 base = (u32) mapping & 0xffffffff;
- return ((base > 0xffffdcc0) &&
- (base + len + 8 < base));
+ return (base > 0xffffdcc0) && (base + len + 8 < base);
}
/* Test for DMA addresses > 40-bit */
{
#if defined(CONFIG_HIGHMEM) && (BITS_PER_LONG == 64)
if (tp->tg3_flags & TG3_FLAG_40BIT_DMA_BUG)
- return (((u64) mapping + len) > DMA_BIT_MASK(40));
+ return ((u64) mapping + len) > DMA_BIT_MASK(40);
return 0;
#else
return 0;
goto out_unlock;
}
- if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
+ if (skb_is_gso_v6(skb)) {
hdrlen = skb_headlen(skb) - ETH_HLEN;
- else {
+ } else {
struct iphdr *iph = ip_hdr(skb);
tcp_opt_len = tcp_optlen(skb);
iph = ip_hdr(skb);
tcp_opt_len = tcp_optlen(skb);
- if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) {
+ if (skb_is_gso_v6(skb)) {
hdr_len = skb_headlen(skb) - ETH_HLEN;
} else {
u32 ip_tcp_len;
{
int i;
- if (tpr != &tp->prodring[0]) {
+ if (tpr != &tp->napi[0].prodring) {
for (i = tpr->rx_std_cons_idx; i != tpr->rx_std_prod_idx;
i = (i + 1) % TG3_RX_RING_SIZE)
tg3_rx_skb_free(tp, &tpr->rx_std_buffers[i],
tpr->rx_jmb_cons_idx = 0;
tpr->rx_jmb_prod_idx = 0;
- if (tpr != &tp->prodring[0]) {
+ if (tpr != &tp->napi[0].prodring) {
memset(&tpr->rx_std_buffers[0], 0, TG3_RX_STD_BUFF_RING_SIZE);
if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE)
memset(&tpr->rx_jmb_buffers[0], 0,
for (j = 0; j < tp->irq_cnt; j++) {
struct tg3_napi *tnapi = &tp->napi[j];
- tg3_rx_prodring_free(tp, &tp->prodring[j]);
+ tg3_rx_prodring_free(tp, &tnapi->prodring);
if (!tnapi->tx_buffers)
continue;
if (tnapi->rx_rcb)
memset(tnapi->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp));
- if (tg3_rx_prodring_alloc(tp, &tp->prodring[i])) {
+ if (tg3_rx_prodring_alloc(tp, &tnapi->prodring)) {
tg3_free_rings(tp);
return -ENOMEM;
}
tnapi->rx_rcb = NULL;
}
+ tg3_rx_prodring_fini(tp, &tnapi->prodring);
+
if (tnapi->hw_status) {
pci_free_consistent(tp->pdev, TG3_HW_STATUS_SIZE,
tnapi->hw_status,
tp->hw_stats, tp->stats_mapping);
tp->hw_stats = NULL;
}
-
- for (i = 0; i < tp->irq_cnt; i++)
- tg3_rx_prodring_fini(tp, &tp->prodring[i]);
}
/*
{
int i;
- for (i = 0; i < tp->irq_cnt; i++) {
- if (tg3_rx_prodring_init(tp, &tp->prodring[i]))
- goto err_out;
- }
-
tp->hw_stats = pci_alloc_consistent(tp->pdev,
sizeof(struct tg3_hw_stats),
&tp->stats_mapping);
memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE);
sblk = tnapi->hw_status;
+ if (tg3_rx_prodring_init(tp, &tnapi->prodring))
+ goto err_out;
+
/* If multivector TSS is enabled, vector 0 does not handle
* tx interrupts. Don't allocate any resources for it.
*/
break;
}
- tnapi->prodring = &tp->prodring[i];
-
/*
* If multivector RSS is enabled, vector 0 does not handle
* rx or tx interrupts. Don't allocate any resources for it.
/* Zero mailbox registers. */
if (tp->tg3_flags & TG3_FLAG_SUPPORT_MSIX) {
- for (i = 1; i < TG3_IRQ_MAX_VECS; i++) {
+ for (i = 1; i < tp->irq_max; i++) {
tp->napi[i].tx_prod = 0;
tp->napi[i].tx_cons = 0;
if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS)
{
u32 val, rdmac_mode;
int i, err, limit;
- struct tg3_rx_prodring_set *tpr = &tp->prodring[0];
+ struct tg3_rx_prodring_set *tpr = &tp->napi[0].prodring;
tg3_disable_ints(tp);
for (i = 0; i < tp->irq_max; i++)
tp->napi[i].irq_vec = msix_ent[i].vector;
- tp->dev->real_num_tx_queues = 1;
+ netif_set_real_num_tx_queues(tp->dev, 1);
+ rc = tp->irq_cnt > 1 ? tp->irq_cnt - 1 : 1;
+ if (netif_set_real_num_rx_queues(tp->dev, rc)) {
+ pci_disable_msix(tp->pdev);
+ return false;
+ }
if (tp->irq_cnt > 1)
tp->tg3_flags3 |= TG3_FLG3_ENABLE_RSS;
if (!(tp->tg3_flags2 & TG3_FLG2_USING_MSIX)) {
tp->irq_cnt = 1;
tp->napi[0].irq_vec = tp->pdev->irq;
- tp->dev->real_num_tx_queues = 1;
+ netif_set_real_num_tx_queues(tp->dev, 1);
}
}
if (err)
goto err_out1;
+ tg3_napi_init(tp);
+
tg3_napi_enable(tp);
for (i = 0; i < tp->irq_cnt; i++) {
err_out2:
tg3_napi_disable(tp);
+ tg3_napi_fini(tp);
tg3_free_consistent(tp);
err_out1:
memcpy(&tp->estats_prev, tg3_get_estats(tp),
sizeof(tp->estats_prev));
+ tg3_napi_fini(tp);
+
tg3_free_consistent(tp);
tg3_set_power_state(tp, PCI_D3hot);
tp->rx_pending = 63;
tp->rx_jumbo_pending = ering->rx_jumbo_pending;
- for (i = 0; i < TG3_IRQ_MAX_VECS; i++)
+ for (i = 0; i < tp->irq_max; i++)
tp->napi[i].tx_pending = ering->tx_pending;
if (netif_running(dev)) {
int num_pkts, tx_len, rx_len, i, err;
struct tg3_rx_buffer_desc *desc;
struct tg3_napi *tnapi, *rnapi;
- struct tg3_rx_prodring_set *tpr = &tp->prodring[0];
+ struct tg3_rx_prodring_set *tpr = &tp->napi[0].prodring;
tnapi = &tp->napi[0];
rnapi = &tp->napi[0];
static void __devinit tg3_read_vpd(struct tg3 *tp)
{
- u8 vpd_data[TG3_NVM_VPD_LEN];
+ u8 *vpd_data;
unsigned int block_end, rosize, len;
int j, i = 0;
u32 magic;
if ((tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) ||
tg3_nvram_read(tp, 0x0, &magic))
- goto out_not_found;
+ goto out_no_vpd;
+
+ vpd_data = kmalloc(TG3_NVM_VPD_LEN, GFP_KERNEL);
+ if (!vpd_data)
+ goto out_no_vpd;
if (magic == TG3_EEPROM_MAGIC) {
for (i = 0; i < TG3_NVM_VPD_LEN; i += 4) {
memcpy(tp->board_part_number, &vpd_data[i], len);
- return;
-
out_not_found:
+ kfree(vpd_data);
+ if (!tp->board_part_number[0])
+ return;
+
+out_no_vpd:
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
strcpy(tp->board_part_number, "BCM95906");
else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 &&
intmbx = MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW;
rcvmbx = MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW;
sndmbx = MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW;
- for (i = 0; i < TG3_IRQ_MAX_VECS; i++) {
+ for (i = 0; i < tp->irq_max; i++) {
struct tg3_napi *tnapi = &tp->napi[i];
tnapi->tp = tp;
tnapi->consmbox = rcvmbx;
tnapi->prodmbox = sndmbx;
- if (i) {
+ if (i)
tnapi->coal_now = HOSTCC_MODE_COAL_VEC1_NOW << (i - 1);
- netif_napi_add(dev, &tnapi->napi, tg3_poll_msix, 64);
- } else {
+ else
tnapi->coal_now = HOSTCC_MODE_NOW;
- netif_napi_add(dev, &tnapi->napi, tg3_poll, 64);
- }
if (!(tp->tg3_flags & TG3_FLAG_SUPPORT_MSIX))
break;