Skip to content

Commit 49a94d7

Browse files
Shannon NelsonJeff Kirsher
authored andcommitted
ixgbe: add ipsec engine start and stop routines
Add in the code for running and stopping the hardware ipsec encryption/decryption engine. It is good to keep the engine off when not in use in order to save on the power draw. Signed-off-by: Shannon Nelson <[email protected]> Tested-by: Andrew Bowers <[email protected]> Signed-off-by: Jeff Kirsher <[email protected]>
1 parent 8bbbc5e commit 49a94d7

File tree

1 file changed

+142
-0
lines changed

1 file changed

+142
-0
lines changed

drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,11 +151,153 @@ static void ixgbe_ipsec_clear_hw_tables(struct ixgbe_adapter *adapter)
151151
}
152152
}
153153

154+
/**
155+
* ixgbe_ipsec_stop_data
156+
* @adapter: board private structure
157+
**/
158+
static void ixgbe_ipsec_stop_data(struct ixgbe_adapter *adapter)
159+
{
160+
struct ixgbe_hw *hw = &adapter->hw;
161+
bool link = adapter->link_up;
162+
u32 t_rdy, r_rdy;
163+
u32 limit;
164+
u32 reg;
165+
166+
/* halt data paths */
167+
reg = IXGBE_READ_REG(hw, IXGBE_SECTXCTRL);
168+
reg |= IXGBE_SECTXCTRL_TX_DIS;
169+
IXGBE_WRITE_REG(hw, IXGBE_SECTXCTRL, reg);
170+
171+
reg = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL);
172+
reg |= IXGBE_SECRXCTRL_RX_DIS;
173+
IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, reg);
174+
175+
IXGBE_WRITE_FLUSH(hw);
176+
177+
/* If the tx fifo doesn't have link, but still has data,
178+
* we can't clear the tx sec block. Set the MAC loopback
179+
* before block clear
180+
*/
181+
if (!link) {
182+
reg = IXGBE_READ_REG(hw, IXGBE_MACC);
183+
reg |= IXGBE_MACC_FLU;
184+
IXGBE_WRITE_REG(hw, IXGBE_MACC, reg);
185+
186+
reg = IXGBE_READ_REG(hw, IXGBE_HLREG0);
187+
reg |= IXGBE_HLREG0_LPBK;
188+
IXGBE_WRITE_REG(hw, IXGBE_HLREG0, reg);
189+
190+
IXGBE_WRITE_FLUSH(hw);
191+
mdelay(3);
192+
}
193+
194+
/* wait for the paths to empty */
195+
limit = 20;
196+
do {
197+
mdelay(10);
198+
t_rdy = IXGBE_READ_REG(hw, IXGBE_SECTXSTAT) &
199+
IXGBE_SECTXSTAT_SECTX_RDY;
200+
r_rdy = IXGBE_READ_REG(hw, IXGBE_SECRXSTAT) &
201+
IXGBE_SECRXSTAT_SECRX_RDY;
202+
} while (!t_rdy && !r_rdy && limit--);
203+
204+
/* undo loopback if we played with it earlier */
205+
if (!link) {
206+
reg = IXGBE_READ_REG(hw, IXGBE_MACC);
207+
reg &= ~IXGBE_MACC_FLU;
208+
IXGBE_WRITE_REG(hw, IXGBE_MACC, reg);
209+
210+
reg = IXGBE_READ_REG(hw, IXGBE_HLREG0);
211+
reg &= ~IXGBE_HLREG0_LPBK;
212+
IXGBE_WRITE_REG(hw, IXGBE_HLREG0, reg);
213+
214+
IXGBE_WRITE_FLUSH(hw);
215+
}
216+
}
217+
218+
/**
219+
* ixgbe_ipsec_stop_engine
220+
* @adapter: board private structure
221+
**/
222+
static void ixgbe_ipsec_stop_engine(struct ixgbe_adapter *adapter)
223+
{
224+
struct ixgbe_hw *hw = &adapter->hw;
225+
u32 reg;
226+
227+
ixgbe_ipsec_stop_data(adapter);
228+
229+
/* disable Rx and Tx SA lookup */
230+
IXGBE_WRITE_REG(hw, IXGBE_IPSTXIDX, 0);
231+
IXGBE_WRITE_REG(hw, IXGBE_IPSRXIDX, 0);
232+
233+
/* disable the Rx and Tx engines and full packet store-n-forward */
234+
reg = IXGBE_READ_REG(hw, IXGBE_SECTXCTRL);
235+
reg |= IXGBE_SECTXCTRL_SECTX_DIS;
236+
reg &= ~IXGBE_SECTXCTRL_STORE_FORWARD;
237+
IXGBE_WRITE_REG(hw, IXGBE_SECTXCTRL, reg);
238+
239+
reg = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL);
240+
reg |= IXGBE_SECRXCTRL_SECRX_DIS;
241+
IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, reg);
242+
243+
/* restore the "tx security buffer almost full threshold" to 0x250 */
244+
IXGBE_WRITE_REG(hw, IXGBE_SECTXBUFFAF, 0x250);
245+
246+
/* Set minimum IFG between packets back to the default 0x1 */
247+
reg = IXGBE_READ_REG(hw, IXGBE_SECTXMINIFG);
248+
reg = (reg & 0xfffffff0) | 0x1;
249+
IXGBE_WRITE_REG(hw, IXGBE_SECTXMINIFG, reg);
250+
251+
/* final set for normal (no ipsec offload) processing */
252+
IXGBE_WRITE_REG(hw, IXGBE_SECTXCTRL, IXGBE_SECTXCTRL_SECTX_DIS);
253+
IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, IXGBE_SECRXCTRL_SECRX_DIS);
254+
255+
IXGBE_WRITE_FLUSH(hw);
256+
}
257+
258+
/**
259+
* ixgbe_ipsec_start_engine
260+
* @adapter: board private structure
261+
*
262+
* NOTE: this increases power consumption whether being used or not
263+
**/
264+
static void ixgbe_ipsec_start_engine(struct ixgbe_adapter *adapter)
265+
{
266+
struct ixgbe_hw *hw = &adapter->hw;
267+
u32 reg;
268+
269+
ixgbe_ipsec_stop_data(adapter);
270+
271+
/* Set minimum IFG between packets to 3 */
272+
reg = IXGBE_READ_REG(hw, IXGBE_SECTXMINIFG);
273+
reg = (reg & 0xfffffff0) | 0x3;
274+
IXGBE_WRITE_REG(hw, IXGBE_SECTXMINIFG, reg);
275+
276+
/* Set "tx security buffer almost full threshold" to 0x15 so that the
277+
* almost full indication is generated only after buffer contains at
278+
* least an entire jumbo packet.
279+
*/
280+
reg = IXGBE_READ_REG(hw, IXGBE_SECTXBUFFAF);
281+
reg = (reg & 0xfffffc00) | 0x15;
282+
IXGBE_WRITE_REG(hw, IXGBE_SECTXBUFFAF, reg);
283+
284+
/* restart the data paths by clearing the DISABLE bits */
285+
IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, 0);
286+
IXGBE_WRITE_REG(hw, IXGBE_SECTXCTRL, IXGBE_SECTXCTRL_STORE_FORWARD);
287+
288+
/* enable Rx and Tx SA lookup */
289+
IXGBE_WRITE_REG(hw, IXGBE_IPSTXIDX, IXGBE_RXTXIDX_IPS_EN);
290+
IXGBE_WRITE_REG(hw, IXGBE_IPSRXIDX, IXGBE_RXTXIDX_IPS_EN);
291+
292+
IXGBE_WRITE_FLUSH(hw);
293+
}
294+
154295
/**
155296
* ixgbe_init_ipsec_offload - initialize security registers for IPSec operation
156297
* @adapter: board private structure
157298
**/
158299
void ixgbe_init_ipsec_offload(struct ixgbe_adapter *adapter)
159300
{
160301
ixgbe_ipsec_clear_hw_tables(adapter);
302+
ixgbe_ipsec_stop_engine(adapter);
161303
}

0 commit comments

Comments
 (0)